NAME¶
Test::Warnings - Test for warnings and the lack of them
VERSION¶
version 0.016
SYNOPSIS¶
use Test::More;
use Test::Warnings;
pass('yay!');
done_testing;
emits TAP:
ok 1 - yay!
ok 2 - no (unexpected) warnings (via done_testing)
1..2
and:
use Test::More tests => 3;
use Test::Warnings 0.005 ':all';
pass('yay!');
like(warning { warn "oh noes!" }, qr/^oh noes/, 'we warned');
emits TAP:
ok 1 - yay!
ok 2 - we warned
ok 3 - no (unexpected) warnings (via END block)
1..3
DESCRIPTION¶
If you've ever tried to use Test::NoWarnings to confirm there are no warnings
generated by your tests, combined with the convenience of
"done_testing" to not have to declare a test count, you'll have
discovered that these two features do not play well together, as the test
count will be calculated
before the warnings test is run, resulting in
a TAP error. (See "examples/test_nowarnings.pl" in this distribution
for a demonstration.)
This module is intended to be used as a drop-in replacement for
Test::NoWarnings: it also adds an extra test, but runs this test
before
"done_testing" calculates the test count, rather than after. It does
this by hooking into "done_testing" as well as via an
"END" block. You can declare a plan, or not, and things will still
Just Work.
It is actually equivalent to:
use Test::NoWarnings 1.04 ':early';
as warnings are still printed normally as they occur. You are safe, and
enthusiastically encouraged, to perform a global search-replace of the above
with "use Test::Warnings;" whether or not your tests have a plan.
It can also be used as a replacement for Test::Warn, if you wish to test the
content of expected warnings; read on to find out how.
FUNCTIONS¶
The following functions are available for import (not included by default; you
can also get all of them by importing the tag ":all"):
"allow_warnings([bool])" - EXPERIMENTAL - MAY BE REMOVED¶
When passed a true value, or no value at all, subsequent warnings will not
result in a test failure; when passed a false value, subsequent warnings will
result in a test failure. Initial value is "false".
When warnings are allowed, any warnings will instead be emitted via
Test::Builder::note.
"allowing_warnings" - EXPERIMENTAL - MAY BE REMOVED¶
Returns whether we are currently allowing warnings (set by
"allow_warnings" as described above).
"had_no_warnings(<optional test name>)"¶
Tests whether there have been any warnings so far, not preceded by an
"allowing_warnings" call. It is run automatically at the end of all
tests, but can also be called manually at any time, as often as desired.
"warnings( { code } )"¶
Given a code block, runs the block and returns a list of all the (not previously
allowed via "allow_warnings") warnings issued within. This lets you
test for the presence of warnings that you not only would
allow, but
must be issued. Testing functions are not provided; given the strings
returned, you can test these yourself using your favourite testing functions,
such as Test::More::is or Test::Deep::cmp_deeply.
Warnings generated by this code block are
NOT propagated further.
However, since they are returned from this function with their filename and
line numbers intact, you can re-issue them yourself immediately after calling
"warnings(...)", if desired.
"warning( { code } )"¶
Same as "warnings( { code } )", except a scalar is always returned -
the single warning produced, if there was one, or an arrayref otherwise --
which can be more convenient to use than "warnings()" if you are
expecting exactly one warning.
However, you are advised to capture the result from "warning()" into a
temp variable so you can dump its value if it doesn't contain what you expect.
e.g. with this test:
like(
warning { foo() },
qr/^this is a warning/,
'got a warning from foo()',
);
if you get two warnings (or none) back instead of one, you'll get an arrayref,
which will result in an unhelpful test failure message like:
# Failed test 'got a warning from foo()'
# at t/mytest.t line 10.
# 'ARRAY(0xdeadbeef)'
# doesn't match '(?^:^this is a warning)'
So instead, change your test to:
my $warning = warning { foo() };
like(
$warning,
qr/^this is a warning/,
'got a warning from foo()',
) or diag 'got warning(s): ', explain($warning);
IMPORT OPTIONS¶
- •
- ":all" - Imports all functions listed above
- •
- ":no_end_test" - Disables the addition of a
"had_no_warnings" test via "END" or
"done_testing"
CAVEATS¶
Sometimes new warnings can appear in Perl that should
not block
installation -- for example, smartmatch was recently deprecated in perl
5.17.11, so now any distribution that uses smartmatch and also tests for
warnings cannot be installed under 5.18.0. You might want to consider only
making warnings fail tests in an author environment -- you can do this with
the if pragma:
use if $ENV{AUTHOR_TESTING} || $ENV{RELEASE_TESTING}, 'Test::Warnings';
In future versions of this module, when interfaces are added to test the content
of warnings, there will likely be additional sugar available to indicate that
warnings should be checked only in author tests (or TODO when not in author
testing), but will still provide exported subs. Comments are enthusiastically
solicited - drop me an email, write up an RT ticket, or come by
"#perl-qa" on irc!
Achtung! This is not a great idea:
sub warning_like(&$;$) {
my ($code, $pattern, $name) = @_;
like( &warning($code), $pattern, $name );
}
warning_like( { ... }, qr/foo/, 'foo appears in the warning' );
If the code in the "{ ... }" is going to warn with a stack trace with
the arguments to each subroutine in its call stack (for example via
"Carp::cluck"), the test name, "foo appears in the
warning" will itself be matched by the regex (see
examples/warning_like.t). Instead, write this:
like( warning { ... }, qr/foo/, 'foo appears in the warning' );
TO DO (or: POSSIBLE FEATURES COMING IN FUTURE RELEASES)¶
- •
- "allow_warnings(qr/.../)" - allow some warnings and not
others
- •
- more sophisticated handling in subtests - if we save some state on the
Test::Builder object itself, we can allow warnings in a subtest and then
the state will revert when the subtest ends, as well as check for warnings
at the end of every subtest via "done_testing".
- •
- sugar for making failures TODO when testing outside an author
environment
SUPPORT¶
Bugs may be submitted through
<
https://rt.cpan.org/Public/Dist/Display.html?Name=Test-Warnings>. I am
also usually active on irc, as 'ether' at "irc.perl.org".
SEE ALSO¶
- •
- Test::NoWarnings
- •
- Test::FailWarnings
- •
- blogs.perl.org: YANWT (Yet Another No-Warnings Tester)
<http://blogs.perl.org/users/ether/2013/03/yanwt-yet-another-no-warnings-tester.html>
- •
- strictures - which makes all warnings fatal in tests, hence lessening
the need for special warning testing
- •
- Test::Warn
- •
- Test::Fatal
AUTHOR¶
Karen Etheridge <ether@cpan.org>
COPYRIGHT AND LICENSE¶
This software is copyright (c) 2013 by Karen Etheridge.
This is free software; you can redistribute it and/or modify it under the same
terms as the Perl 5 programming language system itself.
CONTRIBUTORS¶
- •
- Graham Knop <haarg@haarg.org>
- •
- Leon Timmermans <fawaka@gmail.com>