Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Using Data::Dumper in Test-Driven Development

by dws (Chancellor)
on Aug 05, 2004 at 06:59 UTC ( [id://380203]=perlmeditation: print w/replies, xml ) Need Help??

Data::Dumper is like a carpenter's level. You may catch a glimpse of in use on a job site, but you'll rarely see it in the finished product unless someone got sloppy. I'm working with a team that's been doing Test-Driven Development (TDD) in Perl for a while, using Data::Dumper in an on-the-job-site way I haven't seen described before. In the hope that it turns on lightbulb in someone's dim corner, here's roughly how it works:

When writing a new package using TDD, the idea is to posit a few tests that make assertions about how you want the world to be, and then write the code to make those tests pass. Then more tests, then more code, and so on, with the test file and the package growing in parallel. The tests tend to be black box, but sometimes it helps to peek, particularly for sanity checks.

Our first common use of Data::Dumper is for quick sanity checks as we're bootstrapping tests. At the beginning of a .t file, I might create an instance of the package being developed, and then do a quick dump of it as a sanity check, followed by a test.

my $thing = Thing->new(model => $model); print Dumper $thing; ok( $thing->model, $model );

This is a kind of quick lifting of the veil, making an otherwise black box test white for a brief moment. This also useful when I'm building a larger assemblage, and want a quick verification that I've gotten it right. Once I'm satisfied, the Dumper call goes away. If you hadn't been looking over my shoulder, you'd have missed it, and would have no idea of how useful it had been for that one, brief moment.

Our other common way of using Data::Dumper hinges on the little-known, not exactly well-documented, but not at all surprising fact that Test::ok() returns 0 or 1, reflecting the failure or success of the test. This lets us write

$thing->do_something_interesting(); # the thing's model shouldn't have changed ok( $thing->model, $model ) or print Dumper $thing;

which will both report a failed test and give us diagnostic info to look at. A simple technique, but one that's paid off in time saved when we're taking small, but daring steps, and want rapid feedback that goes beyond "yup, it's broke".

So there it is. The next time you're writing tests cases, try keeping Data::Dumper (or perhaps the new Data::Dumper::Simple) within reach.

And if you're in Silicon Valley, know network management, and want to do XP/TDD in Perl, AirWave is hiring. /msg me for details.

Replies are listed 'Best First'.
Re: Using Data::Dumper in Test-Driven Development
by guha (Priest) on Aug 05, 2004 at 08:50 UTC

    I usually do

    ok( $thing->model, $model ) or diag Dumper $thing;
    which outputs to STDERR and saves one keystroke ;-)

    This way you are guaranteed that your output won't interfere with the tests, even though I'm pretty certain that the Dumper output will not interfere.

Re: Using Data::Dumper in Test-Driven Development
by Ovid (Cardinal) on Aug 05, 2004 at 15:40 UTC

    At the risk of being pedantic, I thought I'd flesh out some information here.

    As guha pointed out, using &diag instead of print is the way to go. &diag prints its messages in such a way so as to play nicely with Test::Harness. It's always possible that simply printing data could result in something that confuses Test::Harness and thus causes unpredictable results which could be hard to diagnose.

    Also, it looks like you're using the venerable Test module instead of Test::More. In the former, your code makes perfect sense. In the latter you'll find that &ok does a simple boolean check, but &is makes the comparison, allows a test name to be assigned and gives very useful diagnostic info.

    $ perl -MTest::More=tests,1 -e 'is(23,42,"Discordia should have the an +swer")' 1..1 not ok 1 - Discordia should have the answer # Failed test (-e at line 1) # got: '23' # expected: '42' # Looks like you failed 1 tests of 1.

    And if you like the new Data::Dumper::Simple, you may wish to note that unlike Data::Dumper, the parentheses are required. That's lamentable, but it made it much easier to implement.

    Cheers,
    Ovid

    New address of my CGI Course.

      Or better yet, combine them both:

      is (23, 42, "Discordia shoud have the answer") or diag "Error in some_code calculating the thing";
      Despite my silly example, when some of the other variations of is are used, the got/expected output isn't always adequate.

Re: Using Data::Dumper in Test-Driven Development
by leriksen (Curate) on Aug 06, 2004 at 02:18 UTC
    I fold Log::Log4perl into our test code too - it allows me to on-the-fly enable messages about the state of the objects/structures concerned. Wrote some code that breaks a test case - just pump up the log level and watch the state of those object/structures change ...
    #!/usr/bin/perl -w use strict; use Test::More qw(no_plan); use Data::Dumper; use Log::Log4perl qw(:levels); use HPA::LT_Utils::File; # the module under test Log::Log4perl->init_and_watch('generic_log.conf', 10); my $logger = get_logger('File'); my $file = HPA::LT_Utils::File->new(undef); is(scalar @{$file->[HPA::LT_Utils::File::_CP]}, 0) or $logger->debug(D +umper($file)); # check internal state is($file->output, '') or $logger->debug('the output() method seems to +have been borked - ', Dumper($file)); # check interface correctness ...

    that example is effectively the same as just prints, the power is in log statements between test cases, when you sometimes want to see the state before some other group of ests run

    # test requirement X is(....); is(....); is(....); $logger->debug('X OK, now test Y ', Dumper($obj)); # test requirement Y is(....); is(....); is(....);

    The advantage is that you aren't constantly adding and deleting print statements - once the log statements are there, you enable/disable them as required.

    use brain;

Log In?
Username:
Password:

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

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

    No recent polls found