What is the most idiomatic way to emulating Perl's Test::More::done_testing?

Posted by DVK on Stack Overflow See other posts from Stack Overflow or by DVK
Published on 2010-05-18T17:26:56Z Indexed on 2010/05/19 20:50 UTC
Read the original article Hit count: 174

Filed under:
|
|

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.

© Stack Overflow or respective owner

Related posts about perl

Related posts about unit-testing