Reputation: 784
I have a set of tests, always named Module.t
, each one starts like this:
use 5.026;
use strict;
use warnings;
use Test::Perl::Critic (-severity => 3);
use Module::Path 'module_path';
use Test::More tests => 8;
use Test::Log4perl;
Test::Log4perl->suppress_logging;
BEGIN { use_ok("My::Module") }
critic_ok(module_path("My::Module"));
... actual tests for this module ...
It's done this way because a bunch of modules are not coded very nicely and in effort to refactor stuff as we go, I'm trying to write tests for individual modules over time. Eg. I can't just enable Perl::Critic for all sources cause it will blow up in my face.
I would like to ideally make a "parent" test for all of these so that when me or a different developer wants to write a new test they will always have all the required stuff. Something like:
use 5.026;
use strict;
use warnings;
# 6 tests because 2 (use_ok and critic_ok) are already in the parent
use parent ParentTest("My::Module", tests => 6);
... actual tests for this module ...
Does perl have a way of doing that?
Disclaimer: I'm a perl noob, so maybe this has a better solution :-)
Upvotes: 1
Views: 90
Reputation: 85767
Sounds like you just want a helper module that loads some other modules and runs some initial tests for you.
Something like:
# ParentTest.pm
package ParentTest;
use strict;
use warnings;
use Test::Perl::Critic (-severity => 3);
use Module::Path 'module_path';
use Test::More;
use Test::Log4perl;
sub import {
my (undef, $module, %args) = @_;
$args{tests} += 2;
plan %args;
Test::Log4perl->suppress_logging;
use_ok $module;
critic_ok module_path $module;
@_ = 'Test::More';
goto +Test::More->can('import');
}
1
Usage would be:
use ParentTest "My::Module", tests => 6;
This is all untested, but the idea is:
Test::More
exports, so our caller doesn't have to use Test::More
themselves.use Some::Module @args
is equivalent to BEGIN { require "Some/Module.pm"; Some::Module->import(@args); }
, so we can just put our custom logic in the import
method.import
is called as a class method) and assigning the remaining arguments to $module
and %args
.$args{tests}
by 2 to account for the two extra tests we perform automatically (if tests
wasn't passed in, it is implicitly created here).%args
to plan
from Test::More
, which is nice for setting up a test plan outside of the initial use
line.Test::More::import
, erasing our own stack frame. This makes it look like our caller did Test::More->import()
, which exports all the Test::More
utility functions to them.+
in goto +Test::More->...
has no real effect, but it helps distinguish between the goto LABEL
and goto EXPRESSION
syntactic forms. We want the latter interpretation.Upvotes: 4