Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Matts (1087)

  (email not shown publicly)

I work for MessageLabs [] in Toronto, ON, Canada. I write spam filters, MTA software, high performance network software, string matching algorithms, and other cool stuff mostly in Perl and C.

Journal of Matts (1087)

Wednesday December 11, 2002
11:47 AM


[ #9382 ]

Testing just saved my ass once more.

I had discovered that for some reason I was only catching about 70% of spam with my code. This worried me a lot. And I've been trying to figure out for a couple of days now what was wrong...

So today I wrote a test script that compared the parsing of mails using my custom mail parser with a different one. Turns out some subtle bugs were causing me to miss boat loads of email.

The good thing is the bug was in my test harness, not in the actual code, so while I found and fixed lots of interesting differences, I also managed to fix my test harness to give me the results I'm after.

In the process I got to use Test::More .

Things I like:

  - More sensible function names than's ok() functions
  - is_deeply() - this rocks.

Things I didn't like much:

  - I found it a bit convoluted to write tests where the number of tests depends on some external data source (e.g. in my case the number of files in a directory). Solutions range from BEGIN blocks to ->import tricks, but none are as simple as: plan tests => $var;

So all in all I prefer it to, but I'm unlikely to use it unless I require it for some reason (such as is_deeply() in this case). Simply because I prefer to keep prereqs to a minimum where I can. Luckily this case is for an internal thing, so I can control the prereq's.

Anyway, kudos to Schwern (and anyone else who helped) for turning Perl into the most testable platform on the planet.

Update: D'oh. I meant Test::More. Of course I've used Test::Harness before. I'd be a fool to have over 50 CPAN modules and not used it :-)

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • turning Perl into the most testable platform on the planet

    This is an excellent point. I wonder if anyone has used Perl's new improved testing features to persuade their bosses to use Perl over some other language.

    How do other languages stack up against Perl in testability?

    • Ruby's Test::Unit [] (by Nathanial Talbott) works well. I haven't used either one very extensively, but I think they're about on par with each other. I've used it to help me catch some bugs while porting Spreadsheet::WriteExcel.

      Someone feel free to disagree...

      • I don't want to disagree, but I still think Ruby has a long way to go in this respect. It still has no unified build framework (unless this has changed recently), and since it doesn't have the above, I'm assuming it doesn't have a unified test harness framework.

        While ruby's Test::Unit looks vaguely interesting, it doesn't look nearly as simple as Test::Harness + (or Test::More). The thing about Test::Harness is that it's not a module, but a tool. And a nice tool at that - it shows me test progress,
  • For testing with a variable number of tests.
  • And here's a neat page that shows how to map out your code coverage for failing and passing tests to show code that is likely to be involved with failed tests:

    Now, when I break a test, I usually know what I changed, so I'm not sure how useful this is for me. For the automated perl smoke tests, it could be cool, though the profiling bit would slow the tests down a lot.

    Anyway, just some cool stuff. See the related work on that site about using antia

  • But the syntax you gave is exactly the syntax for plan under Test::More:
    use Test::More;

    opendir( D, '/etc' ) or die $!;
    my @files = grep { -f } readdir( D );

    plan tests => @files;

    # ...

    See, nice and simple. No BEGIN blocks required. And, as somebody else mentioned, there's always no_plan if you're feeling lazy.


  • Have you considered using Test::More? It has much more useful testing facilities and it allows you to name tests, which can give you very descriptive testing information. Further, if a test fails, it often provides very useful diagnostic information such as telling you what value you were expecting in $foo and what value $foo actually received. Here's a sample from some tests of a "People" object that I have.

    # testing is_senior_contact()

    $sql = <<"END_SQL";
    SELECT people_id, category_id