Yesterday I realized how we can finally have nested TAP and make it backwards compatible. Today I've forked Schwern's Test::More and hacked in nested TAP.
#!/usr/bin/env perl use strict; use warnings; use lib '../lib'; # Gotta have a plan! use Test::More tests => 3; ok 1; subtest 'some name' => sub { my $num_tests = 2 + int( rand(3) ); # random plans! plan tests => $num_tests; ok 1 for 1 .. $num_tests - 1; subtest 'some name' => sub { # or no plans! plan 'no_plan'; ok 1 for 1 .. 2 + int( rand(3) ); }; }; ok 1;
Note how we have random plans and no plans, but we can still have a top-level assertion of the number of tests. The output looks something like this:
1..3 ok 1 1..3 ok 1 ok 2 ok 1 ok 2 ok 3 ok 4 1..4 ok 3 - some name ok 2 - some name ok 3 ok All tests successful. Files=1, Tests=3, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.02 cusr 0.00 csys = 0.04 CPU) Result: PASS
Note that due to how TAP is specified, that's backwards-compatible with older versions of TAP and the current Test::Harness handles this just fine. Andy Armstrong is now working on being able to offer better parsing tools to understand nested TAP.
There is a Test::Builder interface for this, too.
my $builder = Test::Builder->new; $builder->plan(tests => 7); for( 1 .. 3 ) { $builder->ok( $_, "We're on $_" ); $builder->diag("We ran $_"); } { my $indented = $builder->child; $indented->plan('no_plan'); for( 1 .. 1+int(rand(5)) ) { $indented->ok( 1, "We're on $_" ); } $indented->finalize; } for( 7, 8, 9 ) { $builder->ok( $_, "We're on $_" ); }
Eventually we'll add support for being able to compose nested TAP from external sources, but that might require a "TAP envelope" (long story). For now, though, we're ignoring that and focusing on this drool-worthy feature.
So far the Hackathon has been very profitable.