There are tests that you want to have around, but not be part of the standard test run prior to installation of a distribution. Probably the biggest set of these in publicly available Perl distributions is “author” tests (manifest checks, code and POD coverage, etc.), but there are other things such as live database tests that should not block installation. The most common way of disabling tests is via checking an environment variable in a test file:
1 if ( not $ENV{TEST_AUTHOR}) {
2 plan skip_all => ‘Author test. Set $ENV{TEST_AUTHOR} to a true value to run.‘;
3 }
On the Perl::Critic project, we ran into problems with this. We got failures when people had the environment variable set for their own purposes. The code that checked for enabling author tests also turned them on if there was a .svn
directory around, so, of course, we got a complaint when someone grabbed the source from the Perl::Critic repository. *sigh*
The proper way to enable author tests is to require the user to explicitly say that she wants them to be run.
The first thing to do is to segregate the non-standard tests from the regular ones so that the standard testing tools don’t run them by default. At the 2008 QA hackathon in Oslo it was decided that these tests belong under the “xt” directory in a distribution; there was no mandate about substructure. I’ve been using “xt/author” for my author tests.
The second step is to create a “authortest” build target. Since I use Module::Build as my build tool, this example will use that. The way to create a custom target in Module::Build is to create a method on a Module::Build subclass with a name that starts with “ACTION_”. Here’s my standard “authortest” code:
1 sub ACTION_authortest {
2 my ($self) = @_;
3
4 $self->depends_on(‘build‘);
5 $self->depends_on(‘manifest‘);
6 $self->depends_on(‘distmeta‘);
7
8 $self->test_files( qw< t xt/author > );
9 $self->recursive_test_files(1);
10
11 $self->depends_on(‘test‘);
12
13 return;
14 }
First this asks Module::Build to ensure that the build, manifest, and distmeta actions have been run because some of the tests depend upon the MANIFEST and META.yml files being around and I don’t check those into source control. Line 8 tells Module::Build to look in the standard “t” directory plus “xt/author” for tests. Line 9 says that the test files may not be directly in these subdirectories. Finally, it asks for the regular test action to be run.
Using this, running the standard “./Build test
” command doesn’t run author tests, no matter what the user’s environment is. And simply running “./Build authortest
” causes all the tests to run. Simple, yet explicit.
To ensure that nothing gets released without the author tests being run, I change the distdir action to require the author tests be run:
1 sub ACTION_distdir {
2 my ($self) = @_;
3
4 $self->depends_on(‘authortest‘);
5
6 return $self->SUPER::ACTION_distdir();
7 }