My own test functions with Test Builder level
- Test::Builder
- $Test::Builder::Level
Behind the scenes both Test::Simple and Test::More use a module called Test::Builder. Actually Test::Builder is doing the hard work of counting test and displaying error messages. Test::More is just the user friendly front end.
Adding the local $Test::Builder::Level = $Test::Builder::Level + 1; to our own test function will tell Test::Builder to go one level further back in the call stack to find the location where the function was called and where the error occurred.
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 ||= '';
local $Test::Builder::Level = $Test::Builder::Level + 1;
ok( (any {$_ eq $actual} @$expected), 'correct number')
or diag "Received: $actual\nExpected:\n" .
join "", map {" $_\n"} @$expected;
}
Output:
1..8
not ok 1 - correct number
# Failed test 'correct number'
# at t/dice_is_any.t line 16.
# 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 24.
# Received: 1.5
# Expected:
# 1
# 2
# 3
# 4
ok 7 - correct number
ok 8 - correct number
# Looks like you failed 2 tests of 8.