How can I test a standalone Perl script?

Since brian seems to be asleep right now, here's a pointer to what he calls modulinos. This is basically a recipe for building scripts that act like modules or modules that can be run like scripts. Sounds exactly like what you are looking for.

Mastering Perl is definitely a book worth reading (and buying).


I want to do the same thing. Is there a reason not to do the following? (I'm not a perl expert, the solution seems to work fine for me, though.):

in the beginning of the script I ask for a switch ("-test") or whatever and than branch to a sub like this:

my $myargs = CmdLineOptions->new( args=>\@ARGV );
if ($myargs->was_given(option=>"-test"))    { &tests; }

sub tests   {
    require "Test/More.pm";
    Test::More->import('no_plan');

    is(1,1,"my tests go here");
    exit;
}

(by using require and import i suppress the '# No tests run!' message i get when using the 'use Test::More' without doing any tests. I guess it also reduces the overhead.)


It depends on whether you want to test the script itself, or test the subs that make up the script. If you want to test the script, then an external test would be more appropriate, e.g. a shell script. If you want to test the functions that make up the script, then you can either write those tests as more functions within the script or refactor the elements into a Perl module and test the module (which you say you don't want to do).

If the script is small enough, then refactoring might not be necessary. Simply add a '-test' command line argument and call into a test sub, which in turn tests everything else. If doing this, I like to print out a progress indicator of some kind (e.g. a '.' for every test that passes).

If the script is more complex, though, you may want to consider refactoring bits into one or more modules and testing them with Test::Simple or Test::More.


(I do not want to split the script into a separate module and the “executable”, since I plan to distribute the script as a single file.)

Most people stitch files together like this at build time. App::Ack on the CPAN is an example of something that can be built like this.

If you really want to test your application properly, you need to put the functionality in a module, and then write a Test::More-based test script that exercises the functions that the module provides. Then the actual script is just a thin wrapper around the module, usually something like:

#!/usr/bin/env perl
use Your::Class;
Your::Class->new(args => \@ARGV)->run;

See also: MooseX::Getopt.