Conditional TODO Tests
There are some tests which pass, but routinely fail in the debugger. Here's one example:
#!/usr/bin/env perl
use Test::Most tests => 2;
my $sub = sub {
local *__ANON__ = 'anon_sub';
foo(@_);
};
sub foo {
my $arg = shift;
my $subname = ( caller(1) )[3] // '';
$arg++ if 'main::anon_sub' eq $subname;
return $arg;
}
is $sub->(3), 4, 'Calling foo through proxy works';
is foo(3), 3, '... as does calling it directly';
See the bug?
The problem is that by default, the debugger adds "helpful" information to the name of the anonymous subroutine. It becomes something matching ${package}::$subname[${0}:$linenumber] (e,g. in that test: main::anon_sub[caller.t:10]). The fix for this is to add this near the top of your code:¹
BEGIN { $^P ^= 0x200 }
Right. How many of you would know that? I didn't until Tim Bunce pointed it out to me a couple of years ago. It's right there in perldoc perlvar but it's bloody obscure and not really fair to expect the average Perl programmer to remember that.
Other tests which routinely fail under the debugger are time-sensitive tests (this didn't take more than X seconds) when you're slowly stepping through code. It's very annoying running tests through the debugger and see them fail when you know they didn't really fail. That's why I'm thinking about making this easier to handle in Test::Most:
use Test::Most 'no_plan';
debugger_todo {
# tests which fails in the debugger
};
With that, any tests in the block are automatically "todo" tests if run under the debugger.
If it's only the tests which fail under the debugger, this is probably OK. However, if code paths change under the debugger (checking anonymous sub names, for example), then this might not be such a brilliant strategy. Comments welcome.
1. A newer and better solution is to switch to Sub::Name. Thanks to Florian Ragwitz for pointing that out to me.
Leave a comment