Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Get the number of the current test when debugging a test script

by Dumu (Monk)
on Jun 30, 2015 at 11:00 UTC ( [id://1132601]=perlquestion: print w/replies, xml ) Need Help??

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

I'm testing a module I'm developing.

To run the module, I have a test script which initialises the module.

e.g.:
  • tests.t
  • module.pm

There's a bug in the module that is causing the test to fail after a certain test number.

I'd like to run the test using the Perl debugger perl5db.pl and break after the nth test. Is there a way to monitor the variable showing how many tests have been run?

Test::Builder has a $current_test package variable but I can't seem to access it. I'm using Test::Most.


Update:

The answer as I see it

  • Comment on Get the number of the current test when debugging a test script

Replies are listed 'Best First'.
Re: Get the number of the current test when debugging a test script
by choroba (Cardinal) on Jun 30, 2015 at 11:42 UTC
    Can you somehow get to the underlying Test::Builder object? Its Curr_Test contains the current test number:
    #!/usr/bin/perl use warnings; use strict; use Test::Builder; my $o = 'Test::Builder'->new; for (1 .. 3) { $o->ok(1); $o->note($o->{Curr_Test}); } $o->done_testing();
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      So the answer seems to be that you can just create a reference to the $builder object at any time, either in your test script:

      my $builder = Test::Most->builder;

      or in the debugger ('my' doesn't seem to play well on the debugger command line):

      NB for newbies: the DB<x> bit is the debugger prompt, not part of the code.
      DB<x> $builder = Test::Most->builder;

      If you do either of the above, you should find you can subsequently do either of the following in the debugger to print out the current (actually, the latest) test number:

      DB<x> x $builder->{Curr_Test} DB<x> p $builder->{Curr_Test}

      - or, as I originally sought to do, run the debugger and break after a particular test, e.g. test #20:

      DB<x> w $builder->{Curr_Test} == 20 DB<x> c

      Some Monks seem uncomfortable with the idea of running a test script through a debugger. I can sort of understand what you're saying, folks: a test script is effectively a static debugging service, so why run it through the debugger as well? I have a few answers to this but the simplest are:

      "... Perl tests are just Perl code." -- chromatic, in Organizing Perl Test Files
      "TIMTOWTDI!" -- TimToady

      Feel free to get in touch if you would like a couple more.

      Thanks choroba, this is pretty much exactly what I am trying to do.
Re: Get the number of the current test when debugging a test script
by RonW (Parson) on Jun 30, 2015 at 15:56 UTC

    You want a conditional break point. From "perldebug":

    b [line] [condition]

    Set a breakpoint before the given line. If a condition is specified, it's evaluated each time the statement is reached: a breakpoint is taken only if the condition is true. Breakpoints may only be set on lines that begin an executable statement. Conditions don't use if:

    b 237 $x > 30 b 237 ++$count237 < 11 b 33 /pattern/i

    If the line number is ., sets a breakpoint on the current line:

    b . $n > 100

      Yes, but I don't "know" which line to put it on. I don't want to have to trawl through the code manually counting my tests to find which one the test fails after.

      I was disappointed to find that you can't have a conditional watch, actually (e.g. watch for when $var == 3).

      Update

      removed misconception thanks to RonW

      To watch for a variable reaching a certain value, you need

      w (3 == var)

      or just

      w var == 3

        Based on the description in "perdebug":

        w expr

        Add a global watch-expression. Whenever a watched global changes the debugger will stop and display the old and new values.

        I would expect w (3 == $var) to do what you are asking for.

Re: Get the number of the current test when debugging a test script
by 1nickt (Canon) on Jun 30, 2015 at 11:25 UTC

    Hi Dumu,

    If you know which test is failing, why not make a new test script with just that test in it and run under the debugger?

    Also, if you run with perl -d you can step through your code line by line ...

      I suspect Dumu is indicating that it is not the test itself that is problematic, but rather, that the harness breaks after running a certain number of tests.

      If I am interpretting that correctly, moving the test to a new harness and running only one test will not cause the failure in question.

      I could be wrong, but that's how I read it.

        Thanks marinersk, not exactly... the bug was in a specific place in the code. It wasn't being caused by a specific number of tests being run, but it did happen after a certain number of tests had run, simply because that was when the first test was performed on a buggy method.

        But anyone in the situation you describe should also find the answer to my question useful.

      The thing is, I would like to save time by using the debugger to simply watch the relevant variable, rather than tediously stepping through line by line.

      e.g. something like:-

      DB<1> w $current_test DB<2> c
      The debugger should then break whenever the variable's value changes.

      Update

      In fact, the above wouldn't work, since it would stop on every test.

      Update 2

      e.g. something like:-

      DB<1> w $current_test == 8 # NB this doesn't work! DB<2> c

        So why not add your own variable at the point at which you want to stop, in the test in which you want to stop, and have the debugger watch for that? Even that seems way overcomplicated.

        Like jeffa, I get along faster just dumping to STDOUT; you can confess if you need a trace, and in spite of the OP subject line, you do know which test is failing and where, because of the harness output, right?

        Remember: Ne dederis in spiritu molere illegitimi!
      And I just want to be able to do this with the test number.
Re: Get the number of the current test when debugging a test script
by jeffa (Bishop) on Jun 30, 2015 at 16:51 UTC

    "There's a bug in the module that is causing the test to fail after a certain test number."

    But which test number? You wrote the tests ... which test is failing? The output will show you. Since you provided no code and no actual error output, i'll have to supply my own. I changed one value in one my modules and ran the test suite. This was the first error of 14 failed tests in two test files:

    # Failed test 'north: correct HTML from method call' # at ./t/07-theta-presets.t line 106.

    If i look at that test file on line 106 i see:

    is $table->north, $expected, "north: correct HTML from method call";
    From here i have to go back to the definition of north() and this was indeed the function that i changed a value in. No need for a debugger ... i know where the error is now. If i still can't see the error i can fall back on a debugger, but i find that emitting dumps of data to STDERR is faster for me. Read the test output -- if you can't determine where the problem is quickly then your tests are probably too complicated. Tests help to eliminate the need for a debugger if you have exhaustive coverage. Keep your tests simple and fast.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      Thank you for taking the time to answer, jeffa.

      Apologies, the code was highly work-specific and it felt like it would have taken a long time to create an example test and module without adding anything.

      I was interested in the general case of running the standard debugger on any Test::Most (or presumable Test::More or Test::Simple) test script and stopping after a certain test, by number. So I felt that to post code would not necessarily add much helpful info.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1132601]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2024-04-19 08:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found