Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

perl script testing

by pradeep.cbp (Novice)
on Dec 09, 2013 at 06:21 UTC ( [id://1066253]=perlquestion: print w/replies, xml ) Need Help??

pradeep.cbp has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I have set of perl scripts where each script has several options and I need to set up a test to test all these scripts to find whether the script is performing all its options correctly or not. Is there any technique or any perl module to do this???? Thanks in advance

Replies are listed 'Best First'.
Re: perl script testing
by Anonymous Monk on Dec 09, 2013 at 08:08 UTC
Re: perl script testing
by manorhce (Beadle) on Dec 09, 2013 at 06:45 UTC

    cpan provides a very good module for regression test Test::More Please read all the plans provided by the module and use it

Re: perl script testing
by pemungkah (Priest) on Dec 10, 2013 at 01:38 UTC
    There are generally speaking two different ways to test command-line scripts. One, run the script and verify that the script both prints the output expected (on STDOUT and STDERR) and does what you expected it to do (update files, move things, whatever). The other is to build the script in such a way you can unit-test the code without running the whole script.

    The first one can generally be done with IPC::Open3 and Test::Differences; if your script has side effects (file deleted, code checked in to an SCM, etc.), you'll need to use something like Test::More or Test::Unit or Test::Routine to verify the side effects happened. It may be necessary to get a little creative with the side effects tests; for instance, you probably don't want your tests checking code into your central SCM repo, so making the repo configurable is a good idea.

    The second one may actually end up being easier to test. This pattern can be useful (cribbed from How a script becomes a module):

    package MyCode; use strict; use warnings; sub run { # Main routine here } ... rest of implementation here... __PACKAGE__->run() unless caller(); 1;
    This setup allows you to create MyCode.pm and then either use MyCode and write tests (using one of the Test:: packages listed above) for the subs/methods in it, or to simply run MyCode.pm from the command line, which will cause it to call the run() routine and thereby execute the package as a script.
      Thanks for the solution I think 2nd method which you told is suitable to test my scripts.
      I am new for testing and can you please explain what is "# Main routine here" and "... rest of implementation here..." and "__PACKAGE__->run() unless caller();"

      you have told to "write tests for the subs in it" what it means?????
        This is a skeleton of your application to be:
        package MyCode; use strict; use warnings; sub run { # Main routine here } ... rest of implementation here... __PACKAGE__->run() unless caller(); 1;
        The "Main program here" section is going to be the code that basically reads the command line options, figures out what to do, and then calls the other subs or methods to make it happen. The "rest of implementation here" is simply placeholder text to indicate where you'd put the code that actually implements getting things done - that is the code your tests would be testing. The "__PACKAGE__..." line is what makes this .pm file into an executable program; it says "if caller() doesn' return anything (that is, we haven't been loaded by someone else as a module), execute this package's run() method."

        Here's a contrived example.

        package Sample; use strict; use warnings; use GetOpt::Long; __PACKAGE__->run() unless caller(); sub run { my($should_foo); die "usage: Sample.pm [--foo|--bar]\n" unless(GetOptions('foo' => \$should_foo, 'bar' => \$should_bar); my $value = $should_foo ? foo() : bar(); print $value; } sub foo { return "Foo to you too\n"; } sub bar { return "The best bar none\n"; } 1;
        Now in you tests, you can do stuff like this:
        use Test::More tests=>1; use Test::Exception; use Sample; is Sample->bar(), "The best bar none\n", 'bar() works'; is Sample->foo(), "Foo to you too\n", 'foo() works'; local @ARGV; # now undef dies_ok { Sample->run() } 'no args dies as expected'; like $@, qr/^usage:/, 'got a usage message';
        (Note that I have not tested this; it is simply meant to be an illustration of technique.)

        You package has subs that can be tested now to see if they do what they are supposed to. I hope this points you toward a workable direction.

        Edit: Not sure why this is getting down voted - would someone care to comment? Do you disagree with the technique? Do you feel I should have solved the problem more completely? Actual feedback is more useful.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1066253]
Approved by boftx
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2024-04-25 07:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found