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

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??


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 # # <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 1234 1234: 1, 2, 617 Roboticus@Waubli ~ $ perl -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).


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

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

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others rifling through the Monastery: (7)
    As of 2019-10-23 15:11 GMT
    Find Nodes?
      Voting Booth?