Testing Warnings

     

The only parts of your code that don't need tests are those parts that you don't need. If your code produces warnings in certain circumstances and they're important to you, you need to test that they occur when and only when you expect them. The Test::Warn module provides helpful test functions to trap and examine warnings.

How do I do that?

Save the following code as warnings.t :

 use Test::More tests => 4;     use Test::Warn;     sub add_positives     {         my ( $l, $r ) = @_;         warn "first argument ($l) was negative"  if $l < 0;         warn "second argument ($r) was negative" if $r < 0;         return $l + $r;     }     warning_is { is( add_positives( 8, -3 ), 5 ) }         "second argument (-3) was negative";     warnings_are { is( add_positives( -8, -3 ), -11 ) }         [             'first argument (-8) was negative',             'second argument (-3) was negative'         ]; 


Note: There are no commas between the first and second arguments to any of Test:: Warn's test functions because their prototypes turn normallooking blocks into subroutine references .

Run the file with prove to see the following output:

 $  prove -v warnings.t  warnings....1..4     ok 1     ok 2     ok 3     ok 4     ok     All tests successful.     Files=1, Tests=4,  0 wallclock secs ( 0.04 cusr +  0.00 csys =  0.04 CPU) 

What just happened ?

The test file declares and tests a trivial function, add_positives( ) . The function adds two numbers together and warns the user if either number is less than zero.

warning_is( ) takes a block of code to run and the text of the warning expected. Like most other test functions, it takes an optional third argument as the test description. Passing two less-than -zero arguments to add_positives( ) causes the subroutine to produce two warnings. To test for multiple warnings, use Test::Warn 's warnings_are( ) . Instead of a single string, warnings_are( ) takes a reference to an array of complete warning strings as its second argument.

What about...

Q:

What if the warning I'm trying to match isn't an exact string?

A:

Test::Warn also exports warning_like( ) , which accepts a regular expression reference instead of a complete string. Similarly, the warnings_like( ) function takes an anonymous array of regular expression references instead of just a single one. You can shorten warnings.t by using these functions:

 use Test::More tests => 4;     use Test::Warn;     sub add_positives     {         my ( $l, $r ) = @_;         warn "first argument ($l) was negative"  if $l < 0;         warn "second argument ($r) was negative" if $r < 0;         return $l + $r;     }  warning_like { is( add_positives( 8, -3 ), 5 ) } qr/negative/;  warnings_like { is( add_positives( -8, -3 ), -11 ) }         [ qr/first.*negative/, qr/second.*negative/ ]; 

Q:

What if I want to assert that no warnings occur in a specific block?

A:

That's a good test for when add_positives( ) adds two natural numbers. To ensure that a block of code produces no warnings, use Test::Warn 's warnings_are( ) and provide an empty anonymous array:

 warnings_are { is( add_positives( 4, 3 ), 7 ) } [  ]; 

Q:

What if I want to make sure my tests don't produce any warnings at all?

A:

Use the Test::NoWarnings module, which keeps watch for any warnings produced while the tests run. Test::NoWarnings adds an extra test at the end that ensures that no warnings have occurred.

The following listing, nowarn.t , tests the add_positives( ) function and uses Test::NoWarnings . Note that the test count has changed to accomodate the extra test:

 use Test::More  tests => 3  ;     use Test::NoWarnings;     sub add_positives {         my ( $l, $r ) = @_;         warn "first argument ($l) was negative"  if $l < 0;         warn "second argument ($r) was negative" if $r < 0;         return $l + $r;     }     is( add_positives( 4,  6 ), 10 );     is( add_positives( 8, -3 ),  5 ); 

The second test produces a warning, which Test::NoWarnings catches and remembers. When run, the test diagnostics show any warnings that occurred and the most recently run tests.

 nowarn....1..3     ok 1     ok 2     not ok 3 - no warnings     #     Failed test (/usr/local/stow/perl-5.8.6/lib/5.8.6/Test/NoWarnings.pm                     at line 45)     # There were 1 warning(s)     #         Previous test 1 ''     #         second argument (-3) was negative at nowarn.t line 7.     #  at nowarn.t line 7     #         main::add_positives(8, -3) called at nowarn.t line 12     #     # Looks like you failed 1 tests of 3.     dubious         Test returned status 1 (wstat 256, 0x100)     DIED. FAILED test 3         Failed 1/3 tests, 66.67% okay     Failed 1/1 test scripts, 0.00% okay. 1/3 subtests failed, 66.67% okay.     Failed Test Stat Wstat Total Fail  Failed  List of Failed     --------------------------------------------------------------------     nowarn.t       1   256     3    1  33.33%  3 



Perl Testing. A Developer's Notebook
Perl Testing: A Developers Notebook
ISBN: 0596100922
EAN: 2147483647
Year: 2003
Pages: 107

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net