What is the most idiomatic way to emulating Perl's Test::More::done_testing?
- by DVK
I have to build unit tests for in environment with a very old version of Test::More (perl5.8 with $Test::More::VERSION being '0.80') which predates the addition of done_testing().
Upgrading to newer Test::More is out of the question for practical reasons. And I am trying to avoid using no_tests - it's generally a bad idea not catching when your unit test exits prematurely - say due to some logic not executing when you expected it to.
What is the most idiomatic way of running a configurable amount of tests, assuming no no_tests or done_testing() is used?
Details:
My unit tests usually take the form of:
use Test::More;
my @test_set = (
[ "Test #1", $param1, $param2, ... ]
,[ "Test #1", $param1, $param2, ... ]
# ,...
);
foreach my $test (@test_set) {
run_test($test);
}
sub run_test {
# $expected_tests += count_tests($test);
ok(test1($test)) || diag("Test1 failed");
# ...
}
The standard approach of use Test::More tests => 23; or BEGIN {plan tests => 23} does not work since both are obviously executed before @tests is known.
My current approach involves making @tests global and defining it in the BEGIN {} block as follows:
use Test::More;
BEGIN {
our @test_set = (); # Same set of tests as above
my $expected_tests = 0;
foreach my $test (@tests) {
my $expected_tests += count_tests($test);
}
plan tests = $expected_tests;
}
our @test_set; # Must do!!! Since first "our" was in BEGIN's scope :(
foreach my $test (@test_set) { run_test($test); } # Same
sub run_test {} # Same
I feel this can be done more idiomatically but not certain how to improve. Chief among the smells is the duplicate our @test_test declarations - in BEGIN{} and after it.
Another approach is to emulate done_testing() by calling Test::More->builder->plan(tests=>$total_tests_calculated). I'm not sure if it's any better idiomatically-wise.