Now that we created the above is_any function we might want to use it in other tests scripts as well. We might even want to distribute it to CPAN. In order to do that we'll need to move it to a module. The accepted name space for such modules is the Test::* namespace so we are going to use that too. Of course if you are building this for a specific project and not for general use then you are probably better off using the Project::Test::* namespace and if this is intented to be used in-house in a company then it might be better to use Company::Test::* for the name so the chances your module will have the same name as another module in CPAN are small. If written correctly, the only extra thing we need to do is to load the module and import the is_any function. Usually private test modules are placed in the t/lib directory, so we have to add this to our @INC by calling use lib.

examples/perl/t/dice.t
use strict;
use warnings;

use lib 'lib';
use MyTools;

use Test::More tests => 8;

use lib 't/lib';
use Test::MyTools qw(is_any);


for (1..4) {
    my $n = 6;
    my @expected = (1..$n);
    my $value = dice($n);
    is_any($value, \@expected, 'correct number');
}


for (1..4) {
    my $n = 4;
    my @expected = (1..$n);
    my $value = dice($n);
    is_any($value, \@expected, 'correct number');
}

The problematic part is the module. We need the ok and diag functions from the Test::More package but we cannot load the Test::More package as it would confuse the testing system. So instead we are using the Test::Builder backend and the ok and diag methods it provides.

examples/perl/t/lib/Test/MyTools.pm
package Test::MyTools;
use strict;
use warnings;


our $VERSION = '0.01';

use Exporter qw(import);
our @EXPORT_OK = qw(is_any);

use List::MoreUtils qw(any);

use Test::Builder::Module;


my $Test = Test::Builder::Module->builder;


sub is_any {
    my ($actual, $expected, $name) = @_;
    $name ||= '';

    $Test->ok( (any {$_ eq $actual} @$expected), $name) 
        or $Test->diag("Received: $actual\nExpected:\n" 
             . join "", map {"         $_\n"} @$expected);
}

1;


Output:

examples/perl/t/dice.out
1..8
ok 1 - correct number
not ok 2 - correct number
#   Failed test 'correct number'
#   at t/dice.t line 17.
# Received: 1.5
# Expected:
#          1
#          2
#          3
#          4
#          5
#          6
ok 3 - correct number
ok 4 - correct number
not ok 5 - correct number
#   Failed test 'correct number'
#   at t/dice.t line 25.
# Received: 3.5
# Expected:
#          1
#          2
#          3
#          4
ok 6 - correct number
ok 7 - correct number
ok 8 - correct number
# Looks like you failed 2 tests of 8.