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.