My own test functions


After writing lots of tests, you'll see that you need the above code (with the extra diag) in several places in your tests script, so you'll want to refactor it and create a function wrapping it.

The story behind is that the dice() function can actually get any number ($n) and it should then produce a random whole number between 1 and $n. The default is 6. So we are testing dice() with several possible parameters.


examples/test-perl/t/dice_is_any.t
use strict;
use warnings;

use MyTools;

use List::MoreUtils qw(any);

use Test::More tests => 8;


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');
}


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

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

We move the ok() to a function call is_any and we are calling it with the actual value, a reference to an array holding the expected values and the name of the test uint. We had to slightly change the part of the ok() as now we have a reference to the expected values and not the array itself.

Output:


1..8
not ok 1 - correct number
#   Failed test 'correct number'
#   at t/dice_is_any.t line 33.
# Received: 5.5
# Expected:
#          1
#          2
#          3
#          4
#          5
#          6
ok 2 - correct number
ok 3 - correct number
ok 4 - correct number
ok 5 - correct number
not ok 6 - correct number
#   Failed test 'correct number'
#   at t/dice_is_any.t line 33.
# Received: 1.5
# Expected:
#          1
#          2
#          3
#          4
ok 7 - correct number
ok 8 - correct number
# Looks like you failed 2 tests of 8.

This seems to be ok but we have a slight problem here. The row number displayed in the error report is the row number where we actually call the ok() and not where we call the is_any().