Lately I came across a similar issue.
In my case tests were simple boolean values and I so struck to this construct:
#!/usr/bin/perl
use Test2::V0;
for my $mod (11, 4) {
grep {
!($_ % $mod) and !fail "$_ failed";
} 1 .. 10 or pass "all passed mod $mod";
}
done_testing;
__DATA__
# Seeded srand with seed '20211107' from local date.
ok 1 - all passed mod 11
not ok 2 - 4 failed
# Failed test '4 failed'
# at /home/jo/Programs/play-scripts/test-many-grep.pl line 6.
not ok 3 - 8 failed
# Failed test '8 failed'
# at /home/jo/Programs/play-scripts/test-many-grep.pl line 6.
1..3
This is quite simple but has some flaws:
- It is restricted to boolean values, i.e. compare tools cannot be used.
- The number of tests is unpredictable, so plan N cannot be used.
Now that almost the same question was raised, I felt the need for something more advanced than my first attempt.
I never used Test::More, so my solution is based on Test2::V0.
For this purpose a new test tool is generated.
It will execute a code block in the context of a subtest, dropping all passed assertion events.
Any other event will be processed unmodified.
#!/usr/bin/perl
use Test2::V0;
# This would go into a separate package:
use Test2::API qw(context);
use Test2::Tools::Subtest qw(subtest_streamed);
sub drop_passing (&$) {
my ($tests, $name) = @_;
subtest_streamed $name => sub {
my $ctx = context();
my $hub = $ctx->hub;
my $filter = $hub->filter(sub {
my ($hub, $event) = @_;
return if $event->facet_data->{assert}{pass};
$event;
});
$tests->();
$hub->unfilter($filter);
$ctx->pass($name) unless $hub->failed;
$ctx->done_testing;
$ctx->release;
}
}
### end package
plan 4;
pass 'pre test';
for my $mod (11, 4) {
drop_passing {
is $_ % $mod, T(), "check $_" for 1 .. 10;
} "drop passing mod $mod";
}
pass 'post test';
__DATA__
# Seeded srand with seed '20211107' from local date.
1..4
ok 1 - pre test
# Subtest: drop passing mod 11
ok 1 - drop passing mod 11
1..1
ok 2 - Subtest: drop passing mod 11
# Subtest: drop passing mod 4
not ok 1 - check 4
# Failed test 'check 4'
# at /usr/local/share/perl/5.20.2/Test2/API.pm line 676.
# +-----+--------+-------+-----+
# | GOT | OP | CHECK | LNs |
# +-----+--------+-------+-----+
# | 0 | TRUE() | TRUE | 34 |
# +-----+--------+-------+-----+
not ok 2 - check 8
# Failed test 'check 8'
# at /usr/local/share/perl/5.20.2/Test2/API.pm line 676.
# +-----+--------+-------+-----+
# | GOT | OP | CHECK | LNs |
# +-----+--------+-------+-----+
# | 0 | TRUE() | TRUE | 34 |
# +-----+--------+-------+-----+
1..2
not ok 3 - Subtest: drop passing mod 4
# Failed test 'Subtest: drop passing mod 4'
# at /home/jo/Programs/play-scripts/test-many.pl line 25.
ok 4 - post test
Now any tests may be used within drop_passing and these count as a single test.
Though this won't be of much help for users of Test::More I'd like to share it anyway.
Greetings, -jo
$gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
|