Alternative to Test::NoWarnings

The Test::NoWarnings module is very helpful for detecting subtle errors in your code. Unfortunately, by default, it does its reporting in an END block, which doesn’t play nicely with Test::More’s done_testing() function, which I use a lot. There has been an open ticket since 2009 and nothing has been done.

There is a workaround, but it’s a lot more verbose than I’d like:

use Test::More;
use Test::NoWarnings (); # skip import

# ... tests ...

Test::NoWarnings::had_no_warnings;
done_testing;

That’s OK, but annoying to put over and over again in every .t file. (Even if I automate it with an editor macro).

Today I released a much simpler alternative called Test::FailWarnings. It just hooks $SIG{__WARN__} and turns warnings into Test::More fail() calls. This works well with done_testing(), because you can’t plan for these being called or not.

Also, it issues the failures as they happen, instead of storing them up for the end. That’s either a feature or a bug, depending on how you like to debug your failures.

Here’s the obligatory example from the synopsis:

use strict;
use warnings;
use Test::More;
use Test::FailWarnings;
 
ok( 1, "first test" );
ok( 1 + "lkadjaks", "add non-numeric" );
 
done_testing;

When run, it produces output like this:

ok 1 - first test
not ok 2 - Caught warning
#   Failed test 'Caught warning'
#   at t/bin/main-warn.pl line 7.
# Warning was 'Argument "lkadjaks" isn't numeric in addition (+) at t/bin/main-warn.pl line 7.'
ok 3 - add non-numeric
1..3
# Looks like you failed 1 test of 3.

I’m sure there are many ways in which Test::FailWarnings is too simplistic, (I welcome ideas or contributions), but I’m tired of waiting for a fix and this meets my needs now.