Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should I put common utility functions for Perl .t tests?

Tags:

testing

perl

I am getting started with Test::More, already have a few .t test scripts. Now I'd like to define a function that will only be used for the tests, but across different .t files. Where's the best place to put such a function? Define another .t without any tests and require it where needed? (As a sidenote I use the module structure created by Module::Starter)

like image 697
zedoo Avatar asked May 14 '10 12:05

zedoo


2 Answers

The best approach is to put your test functions, like any other set of functions, into a module. You can then use Test::Builder to have your test diagnostics/fail messages act as if the failure originated from the .t file, rather than your module.

Here is a simple example.

package Test::YourModule;

use Test::Builder;
use Sub::Exporter -setup => { exports => ['exitcode_ok'] };  # or 'use Exporter' etc.

my $Test = Test::Builder->new;

# Runs the command and makes sure its exit code is $expected_code. Contrived!
sub exitcode_ok {
    my ($command, $expected_code, $name) = @_;

    system($command);
    my $exit    = $? >> 8;
    my $message = $!;

    my $ok = $Test->is_num( $exit, $expected_code, $name );
    if ( !$ok ) {
        $Test->diag("$command exited incorrectly with the error '$message'");
    }

    return $ok;
}

In your script:

use Test::More plan => 1;
use Test::YourModule qw(exitcode_ok);
exitcode_ok('date', 0, 'date exits without errors');
like image 127
rjh Avatar answered Nov 18 '22 12:11

rjh


Write a module as rjh has demonstrated. Put it in t/lib/Test/YourThing.pm, then it can be loaded as:

use lib 't/lib';
use Test::YourThing;

Or you can put it straight in t/Test/YourThing.pm, call it package t::Test::YourThing and load it as:

use t::Test::YourThing;

The upside is not having to write the use lib line in every test file, and clearly identifying it as a local test module. The down side is cluttering up t/, it won't work if "." is not in @INC (for example, if you run your tests in taint mode, but it can be worked around with use lib ".") and if you decide to move the .pm file out of your project you have to rewrite all the uses. Your choice.

like image 21
Schwern Avatar answered Nov 18 '22 13:11

Schwern