Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Test framework for simple command-line script?

by loris (Hermit)
on Jun 12, 2008 at 09:26 UTC ( #691617=perlquestion: print w/replies, xml ) Need Help??
loris has asked for the wisdom of the Perl Monks concerning the following question:

Hello all,

I have just had the problem that a script using Getopt::Long tried to use the same option as both lowercase and uppercase. This was easily fixed (with Getopt::Long::Configure('no_ignore_case')). However, I started wondering what sort of testing framework would be best for this situation.

The script is short (less than 200 LoC) and really is just a script. In the past I have turned scripts into modules and then used Test::Simple or Test::More, but in this case, this seems like it would be overkill. Is, as suggested here, Test::Cmd the way to go?



"It took Loris ten minutes to eat a satsuma . . . twenty minutes to get from one end of his branch to the other . . . and an hour to scratch his bottom. But Slow Loris didn't care. He had a secret . . ." (from "Slow Loris" by Alexis Deacon)

Replies are listed 'Best First'.
Re: Test framework for simple command-line script?
by andreas1234567 (Vicar) on Jun 13, 2008 at 06:21 UTC
    Yes, you can certainly use Test::Cmd e.g. like this: 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(''); 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]

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://691617]
Approved by bingos
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2018-06-19 15:07 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (114 votes). Check out past polls.