Perl Test::More and setting up test requirements
With Test::More
I often want to have a module that runs tests and has the ability to abort the callers test_plan
. I have a series of tests that set up a plugin list for Catalyst::Test
. I don't want to have to make my test check to see if they exist; instead, I want my script to abort if those plugins aren't present.
I was trying to track down a bug in my Catalyst::Authentication::Store::DBI::ButMaintained
, and I noticed this bug is also present in Catalyst::Authentication::Store::DBI
. Here it is:
eval {
require Catalyst::Model::DBI;
require Catalyst::Plugin::Session;
require Catalyst::Plugin::Session::State::Cookie;
require Catalyst::Plugin::Session::Store::File;
require DBD::SQLite;
require Test::WWW::Mechanize::Catalyst;
} or plan skip_all => $@;
...
$ENV{'TESTAPP_PLUGINS'} = [ qw(
Authentication
Session
Session::Store::File
Session::State::Cookie
Authorization::Roles
) ];
As you can see, the eval/skip_all
doesn't check Authorization::Roles
inclusion, but the test depends on it by virtue of it being a plugin.
I have another question though -- is there a more elegant way to specify Test-dependencies than this? Keep in mind my goal is the same as the ori开发者_如何学Cginal authors. I simply want to skip the test, if the test requirements don't exist. Ideally, in this case, I'd like to hack Catalyst::Test
to wrap the plugin mechanism for Catalyst::Plugin::*
stuff, and then find a better way to do the rest of this stuff without eval/skip_all
.
You can dynamically affect the # of tests in the plan by calling:
Test::More->builder->plan(tests=>$total_tests);
You can use that do conditionally calculate the # of tests based on the needs.
Update with your list of plugins as needed:
If you are testing a bunch of requirements in a separate package, you could simply have that package return false (rather than the traditional true value) if a dependency is not met:
package Catalyst::Test;
eval {
use Dep1;
use Dep2;
# ...
}
# dep check package returns true if we found all the modules
!$@;
# test.pl
use Test::Requires {
Catalyst::Test => 0.01, # skip all tests if Catalyst::Test is not present
};
use Test::More tests => 20; # call Test::More as normal.
When I run this using a dep checker called Foo
, this fails with appropriate output:
% perl -I. foo.t 1..0 # SKIP Foo.pm did not return a true value at (eval 4) line 2. # BEGIN failed--compilation aborted at (eval 4) line 2. #
% prove -I. foo.t foo.pl .. skipped: Foo.pm did not return a true value at (eval 4) line 2. Files=1, Tests=0, 0 wallclock secs ( 0.02 usr 0.01 sys + 0.01 cusr 0.00 csys = 0.04 CPU) Result: NOTESTS
精彩评论