secondturtle has asked for the wisdom of the Perl Monks concerning the following question:

At work we're trying to better organize our system of tests. We are leaning towards Test::Class and spent all of yesterday writing tests using Test::Class. Any approach to testing has its strengths and weaknesses. One of the weaknesses we identified with Test::Class is its reluctance to play nicely with the perl debugger.

Some of us would like the have the ability to set a breakpoint at the beginning of a test method and step through the test in the debugger. Going about this in the normal way of starting the program, setting the breakpoint, and letting the debugger continue until the breakpoint is reached does not seem to work.

Sample test class:

package A; use strict; use warnings; use base 'Test::Class'; use Test::More; sub test_foo :Test(no_plan) { pass('foo'); } 1;

Debugger session (slightly abridged):

~$ perl -d -MA -e 'Test::Class->runtests' Loading DB routines from perl5db.pl version 1.28 Attribute::Handlers::CODE(0x82d4198)(/usr/lib/perl5/5.8.7/Attribute/Ha +ndlers.pm:206): 206: $global_phase++; DB<1> b A::test_foo DB<2> c ok 1 - foo 1..1 Debugged program terminated. DB<2> q ~$

So after setting the breakpoint and continuing, the debugger executes test_foo and the program ends before the debugger prompt returns. One way to force the debugger to stop at the beginning of the subroutine is to insert a $DB::single=1 into the code where the breakpoint would be.

I'm looking for ways to add breakpoints without modifying the code in a way that is as close as possible to how people already use the debugger. I'll update this post if I find any.

Replies are listed 'Best First'.
Re: Using debugger breakpoints in Test::Class code
by belden (Friar) on Nov 13, 2008 at 23:42 UTC
    Why don't you want to add the $DB::single line?

    At work we have a key-binding in our editor that drops these two lines at the cursor:

    local $MY::var = 1; # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX $DB::single = 1 if $MY::var; # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    When debugging code, we'll generally drop the $MY::var = 1 line into some test block, and stick the $DB::single line into whatever method we're debugging. Works fine.

      > Why don't you want to add the $DB::single line?
      For all the same reasons the debugger supports adding breakpoints while debugging.

      Also, many times when I'm debugging is when I decide where I want to add a breakpoint. I don't want to have to restart the debugger and lose my position in the executing program's call stack just to add a break point. That's annoying.

      Adding a $DB::single=1 code works, but it's far from ideal.

Re: Using debugger breakpoints in Test::Class code
by jimX11 (Friar) on Nov 16, 2008 at 22:24 UTC
    Gerard Meszaros wrote a wonderful book on refactoring tests - xUnit Test Patterns (amazon link)
    He lists code smells:
    • Eager Test (testing too much at once)
    • Conditional Test Code (he suggests limiting the use of "if" in tests)
    • Obscure Test (what is being tested?)
    • Test Code Duplication
    At $work I cleaned up our test suite just a bit, removing eager tests, conditional logic and obscure tests. I haven't use Test::Class.
    Meszaros says test could should be drop dead simple.

      Funny that you would cite a book about xUnit testing in an attempt to support your suggestion that I shouldn't be using the most widely adopted perl implementation of xUnit.

      I haven't read Meszaros's book (yet), but it sounds like he knows what he's talking about. Thanks for the suggestion.