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'; 

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

About Ovid

user-pic Have Perl; Will Travel. Freelance Perl/Testing/Agile consultant. Photo by Warning: that site is not safe for work. The photographer is a good friend of mine, though, and it's appropriate to credit his work.