Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Zenzizenzizenzic:

You could always try adding a command-line option to invoke a test routine and quit instead of running normally. Suppose, for example, you have the following program:

#!env perl # # factor.pl <Number> # # Print the list of prime factors for Number # # 20130206 Can't find a copy on my hard drive, so making it again use strict; use warnings; my $num = shift or die "Expected number to factor!"; print "$num: ", join(", ", factors($num)), "\n"; sub factors { my $val=shift; return unless $val; my @primes = (1); if ($val < 0) { unshift @primes, -1; $val = -$val; } while ($val % 2 == 0) { push @primes, 2; $val = $val/2; } my $fac=3; while ($fac*$fac <= $val) { while ($val % $fac == 0) { push @primes, $fac; $val = $val / $fac; } $fac += 2; } push @primes, $val if $val > 1; return @primes; }

Suppose further that you wanted to make sure that the factors routine was tested. You could create a routine with some tests like this:

sub do_tests { use Test::More; use Data::Dump 'pp'; my @test_cases = ( [ 0, [] ], [ 1, [1] ], [ 2, [1, 2] ], [ 3, [1, 3] ], [ 4, [1, 2, 2] ], [ -72, [-1, 1, 2, 2, 2, 3, 3] ], ); for my $case (@test_cases) { my @f = factors($case->[0]); # Uncomment for debugging #print "$case->[0], exp: (", join(",",@{$case->[1]}), "), got( +", join(",",@f),")\n"; is_deeply([@f], $case->[1]); } done_testing(); }

and then change the line that calls it and prints the results to this:

if ($num eq "-test") { do_tests(); } else { print "$num: ", join(", ", factors($num)), "\n"; }

So now, I can either use the program normally, or test it:

$ perl pm_1224882.pl 1234 1234: 1, 2, 617 Roboticus@Waubli ~ $ perl pm_1224882.pl -test ok 1 ok 2 ok 3 ok 4 ok 5 ok 6 1..6

Unfortunately, a lot of code that was written without tests can be tricky to test. Writing code with tests tends to change your coding style to make your code more testable. So while this trick may help you on your way to starting to get some of your code tested, be aware that retrofitting tests to code you currently have can be a bit tricky.

I'd suggest trying to add testing where you can, though, as it can make your code better. I don't see any problems with using a trick like this as a starting point.

In fact, when writing this response, I found a couple cases where my factors routine didn't work. It had an infinite loop if you gave it 0 (it would keep adding '2' to the factors while checking for even numbers), and I didn't make it work for negative numbers at all. The act of me coming up with a few simple test cases made me find and fix those bugs. This little thing has been on my computer for over five years, and I hadn't encountered a problem with it yet. (Not surprising, as I wouldn't call this script to factor 0 or a negative number. But had I moved factors() into one of my libraries and assumed it was fully tested, it would have been found wanting the first time it tried factoring a negative number or 0.

Another nice thing about test cases is that they can provide some basic documentation on how to use the function, should the comments be inadequate. For example, I should probably return 1, 0 for the factors of 0, but for my purposes, I prefer an empty list, so I'm leaving it that way. If I decide to reuse factors() for another purpose, the result for 0 should be obvious from the test, and I can change the code accordingly if I want 1, 0 in the other use case(s).

...roboticus

When your only tool is a hammer, all problems look like your thumb.


In reply to Re: Needing help on testing by roboticus
in thread Needing help on testing by Zenzizenzizenzic

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
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-24 10:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found