Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Testing programs

by lhoward (Vicar)
on Oct 25, 2005 at 12:47 UTC ( #502691=perlquestion: print w/replies, xml ) Need Help??

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

The Perl modules for automating tests seem to be built for testing other modules, not programs. I've been pondering what I should do to test the internals of programs beside external tests (running the program with various inputs and checking the outputs). What I'm looking for is a spot in the middle, where I can run some tests on my program to verify that various subroutines are functioning as expected.

I've done some experiments and the following example is the best idiom that I have been able to come up with so far. Am I on the right track? Am I using a hammer when I should be using a screwdriver? if so, who has the screwdrivers?
#!/usr/bin/perl use warnings; use strict; use Getopt::Std; our ($opt_t); getopts('t'); if($opt_t){ eval 'use Test::Simple tests => 3;'; ok(double(2) == 4); ok(double(-3) == -6); ok(double(0) == 0); exit; } print join ' ',map(double($_),@ARGV),"\n"; sub double{ my $a=shift; $a*2; }

Replies are listed 'Best First'.
Re: Testing programs
by sauoq (Abbot) on Oct 25, 2005 at 13:05 UTC

    Why use a command line argument for testing? I sometimes stick my tests in a separate file and do() them when I want to.

    In my program...

    #!/usr/bin/perl use warnings; use strict; do ""; sub foo { "foo" }
    And then in ...
    use Test::Simple tests => 1; ok( foo() eq 'foo' ); exit;

    Then I can just comment out my do ""; line when I'm done with it.

    "My two cents aren't worth a dime.";
Re: Testing programs
by pboin (Deacon) on Oct 25, 2005 at 13:08 UTC

    This got me for a while too. The way you're doing it seems to be commonly accepted. I think that if you have procedural functions, you can also require it, and then use the test harness against the subroutines.

    One of the most important concepts I got from the thread was that you definitely do not want to get into testing a copy of your code. That will inevitably lead to problems w/ syncronization (and hassle).

    Here's a good thread on it: Testing Non-module code

Re: Testing programs
by xdg (Monsignor) on Oct 25, 2005 at 13:56 UTC

    You might want to look at How a script becomes a module. The idea described there is to write the program in a way that can be loaded as a module for testing specific subroutine functionality, or can be run as a program. For the more macro input/output testing, you may also want to see the template I offered in Re: Test driven development and glue code


    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Testing programs
by Perl Mouse (Chaplain) on Oct 25, 2005 at 14:51 UTC
    I'd separate out the testing from the program. It makes your code cleaner, and you won't pay the costs of compiling your test suite each time you run the program.
    # Main program: #!/usr/bin/perl use strict; use warnings; sub double { my $n = shift; return $n * 2; } return 1 if caller; # Don't leave this out. print join ' ', map {double($_)} @ARGV; print "\n"; __END__ # Test program: #!/usr/bin/perl use strict; use warnings; use Test::Simple tests => 3; require ''; # Substitute the name of your program. ok(double( 2) == 4); ok(double(-3) == -6); ok(double( 0) == 0); __END__
    Perl --((8:>*
Re: Testing programs
by blazar (Canon) on Oct 25, 2005 at 13:22 UTC
    The Perl modules for automating tests seem to be built for testing other modules, not programs.
    First of all I'm not an expert wrt these issues, and I apologize in advance if I'm about to say something utterly stupid, but a possibility that springs to mind would be to write a wrapper sub for your program that would return the output of the latter as, say, returned by qx// and check that.
    if($opt_t){ eval 'use Test::Simple tests => 3;'; ok(double(2) == 4); ok(double(-3) == -6); ok(double(0) == 0); exit; }
    So you want to run tests dependently from a cmd line switch. I don't think this is a common practice, but I don't see anything patently wrong with it. Though, incidentally, I'd try to avoid string eval and resort to a require, if possibly slightly more verbose...

Log In?

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

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2023-12-06 03:45 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (29 votes). Check out past polls.