Monday 18 January 2010

Better output testing HTML and other long strings

If you ever wrote or ran a website test in Perl, you probably used Rafaël Garcia-Suarez's wonderful Test::LongString, even if you never heard of it before. Not only is it used by lots of CPAN modules, it is the foundation of Test::WWW::Mechanize test functions, with flavors for Catalyst, PSGI, CGIApp and several others. But it doesn't have to be HTML content testing - any string output can be tested with its awesome functions.

Maybe Test::LongString's most common function is contains_string(), which you may know as Test::WWW::Mechanize's $mech->content_contains() method. When it fails, the failing test output shows the original string and the text it was trying to find:


# searched: "foo bar"
# can't find: "baz"


Problem is, when the original string is too long, you get only the beginning of it. This happens a lot when you're trying to find content inside HTML, like:


# searched: "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Trans"...
# can't find: "some random content"


Such output is only barely useful, and I got fed up of having to edit a test file manually, add diag() calls to see the complete output, then ack for the wanted string to see what went wrong. So I made a small patch to Test::LongString, which Rafaël promptly accepted (yup, he rocks, but we all know that ;-).

Now, whenever such test fails, you'll get two extra lines:


# searched: "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Trans"...
# can't find: "some random content"
# LCSS: "ome random content"
# LCSS context: "d="content" class="foo">Some random content!</div>"


"LCSS" stands for Longest Common SubString, meaning you get whatever matched the most inside the original content (note that LCSS is not the same as LCS, or Longest Common Subsequence, which would go for a non-sequential match as seen in diff-like outputs). And, of course, "LCSS context" means the surroundings of the LCSS string just found.

Now, just by looking at our example, we know exactly why the test failed, and we are free to fix either the test suite or the application.

Know what's best? You get all that for free, no need to change a single line in your tests. Just update Test::LongString to 0.12 or later and enjoy! :-)

Monday 4 January 2010

First CPAN upload of 2010

Hi everyone - happy new year!

2009 came and went, so here's to an amazing 2010 for the Perl world, with even more than we already accomplished last year :-)

And look at that, it's only day 4 of 2010 and we already saw over 200 CPAN uploads. But don't look just yet! See if you can figure out what was the very first package upload to CPAN in 2010 (CPAN-time, of course). No clue? Couldn't care less? Well, call me curious, but I had to look ;-)

January 1st had several heavy competitors: PDL, Chart::Clicker, POE... even Plack was this close from being the one. But our "winner" is a rather young package by Marty O'Brien. I'm talking about Forks::Super, in it's 12th release.

Forks::Super provides new definitions for the Perl functions fork, wait, and waitpid with richer functionality. The new features are designed to make it more convenient to spawn background processes and more convenient to manage them and to get the most out of your system's resources. Take good old fork(), for example. Without arguments, it behaves just like it used to, but now you can also do stuff like:

     my $pid = fork { cmd => [ qw(/bin/prog opt1 $opt2 opt3) ] };
or
     my $pid = fork { sub => \&subroutine, args => [ @args ] };

Your can even set timeouts on your forks, queue jobs and obtain filehandles. Pretty cool, huh?

I haven't actually used it, but Marty took his time with a very comprehensive Pod, and even some information for windows users. So, if you usually use fork in your programs, be sure to check it out.

Until next time!