Testing Perl Code – Suppressing Warnings
A lot of developers I have worked with have been amazed to see that I expand a suite of tests they developed by a factor of four. This is almost always because I am stressing error handling which is often not tested at all. Unfortunately, these tests will often cause many warnings. Sometimes I want to verify the exact warning. Other times it just clutters the output being sent to the screen. This can be very dangerous – it may lead someone running the test to believe there is a newly introduced bug.
Luckily, perl has a well defined mechanism for overriding the warn behavior. If you want to suppress warnings from being displayed in a section of tests do the following:
- Scope the section of code where you want to suppress the warnings:
{ ... }
- Define your own warning handler inside the scoped code:
{
local $SIG{__WARN__}=sub{}; #Temporarily suppress warnings
# Insert test code here
}
Once the scoping ends, whatever warning handler was in effect before will be active again.
2 Comments
hi,
i m new to testing, i would like to know hw to test already developed code in perl
Thanks! Just what I was looking for. Cooked up a uitility method if anyone is interested.
# Executes the supplied code returning a hashref:
# ‘warnings’ => arrayref of any warning messages
# ‘warning’ => most recent warning message
# ‘result’ => executed code result
#
# my $run = trap_warn( sub { warn ‘tjoho!’; return 2 } );
#
# print $run->{‘warnings’}[0]; # ‘tjoho!’
# print $run->{‘warning’}; # ‘tjoho!’
# print $run->{‘result’}; # 2
my $DIAG_TRAPPED_WARNS = 0;
sub trap_warn {
my $code = shift;
my @warn_message = ();
local $SIG{__WARN__} = sub {
push @warn_message, shift;
diag “Trapped warn: “.$warn_message[-1] if $DIAG_TRAPPED_WARNS;
};
my $result = # Run code
return { ‘warnings’ => \@warn_message,
‘warning’ => pop @warn_message,
‘result’ => $result };
}