in reply to Test framework for simple command-line script?

Yes, you can certainly use Test::Cmd e.g. like this:
$ cat 691617.pl #!/usr/bin/perl use strict; use warnings; use Getopt::Long; my $help; my $test; my $file; GetOptions( "help|?" => \$help, "t|test" => \$test, "f|file=s" => \$file ) or die "arg error"; die "No such file '$file'" if ($file && ! -f $file); 1; __END__ $ cat 691617.t use strict; use warnings; use Test::More; use Test::Cmd; plan tests => 7; my $test = Test::Cmd->new( prog => '691617.pl', interpreter => '/usr/bin/perl', workdir => '', ); # These tests are expected to pass $test->run(args => '-f 691617.pl'); ok($? == 0, "executing 691617.pl -f 691617.pl"); $test->run(args => '-t'); ok($? == 0, "executing 691617.pl -t"); $test->run(args => '--help'); ok($? == 0, "executing 691617.pl --help"); $test->run(args => '?'); ok($? == 0, "executing 691617.pl ?"); # These tests are expected to fail $test->run(args => '-g'); ok($? != 0, "executing 691617.pl -g - expected failure"); $test->run(args => '-f no_such_file'); ok($? != 0, "executing 691617.pl -f no_such_file - - expected failure" +); $test->run(args => '-f'); ok($? != 0, "executing 691617.pl -f <missing argument> - expected fail +ure"); __END__ $ prove 691617.t 691617....ok All tests successful. Files=1, Tests=7, 1 wallclock secs ( 0.37 cusr + 0.05 csys = 0.42 C +PU) $
However, I would probably choose to refactor the code into separate subroutines to make it more testable. This means you can test parts of the script separately and independently of the other parts (which you can't easily do with Test::Cmd). Second, I would use the main() unless caller() trick from Perl Testing: A Developer's Notebook. This trick makes the script context-aware in the sense that it will only invoke main when called directly (i.e. when there's no call stack - in other words: When we're not testing). In effect it lets you invoke parts of the script only, much like loading a module (without executing its' contents).
use strict; use warnings; sub do_this { return 2 + 2; } sub do_that { return 3 + 3; } sub main { my $i = do_this(); my $j = do_that(); } main() unless caller(); # make it testable 1; __END__
The test could then be:
use strict; use warnings; use Test::More; plan tests => 3; require_ok('foo.pl'); cmp_ok(do_this(), '==', 4, 'expect do_this() to return 4)'); cmp_ok(do_that(), '==', 6, 'expect do_that() to return 6)'); __END__
Run it:
$ prove foo.t foo....ok All tests successful. Files=1, Tests=3, 1 wallclock secs ( 0.04 cusr + 0.01 csys = 0.05 C +PU)
I recommend the book. Happy testing.
--
No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]