Testing Programs

     

Perl's a great glue language and there are a lot of other programs in the world worth gluing together ”or at least using from your own programs. Maybe your project relies on the behavior of other programs not under your control. That makes them worth testing. Maybe your job is testing, and you've realized that Perl and its wealth of testing libraries would be nice to have to test code written in other languages.

Whatever your motivation, Perl is perfectly capable of testing external programs. This lab shows how.

If you have one program on your machine to run all of the examples in this book, it's the Perl executable itself. That makes it a great candidate to test, especially for things you can't really test from within Perl. For example, the Perl core has its own test suite. How does it test Perl's command-line flags that print messages and exit? How does it test whether bad code produces the correct fatal compiler warnings? It runs a fresh Perl instance and examines its output.

You can do the same.


Note: See _fresh_perl() and _fresh_perl_ is()in t/test.pl in the Perl source code .

How do I do that?

Save the following test file as perl_exit.t :

 #!perl          use strict;     use warnings;          use IPC::Run 'run';     use Test::More tests => 7;          my ($out, $err) = runperl( '-v' );     like($out, qr/This is perl/, '-v should print short version message'      );     is(  $err, '',               '... and no error'                           );          ($out, $err)    = runperl( '-V' ) ;     like($out, qr/Compiled at/,  '-V should print extended version message'   );     is(  $err, '',               '... and no error'                           );          ($out, $err)    = runperl(qw( -e x++ ));     like($err, qr/Can't modify constant.+postincrement/,                                 'constant modification should die with error' );     like( $err, qr/Execution.+aborted.+compilation errors/,                             '... aborting with to compilation errors'     );     is( $out, '',           '... writing nothing to standard output'      );          sub runperl     {         run( [ $^X, @_ ], \my( $in, $out, $err ) );         return ($out, $err);     } 


Note: The special variable $^X contains the path to the currently running Perl executable. It comes up often in testing .

Run the test file with prove :

 $  prove perl_exit.t  perl_exit....ok     All tests successful.     Files=1, Tests=6,  1 wallclock secs ( 0.28 cusr +  0.05 csys =  0.33 CPU) 

What just happened ?

The IPC::Run module provides a simple and effective cross-platform way to run external programs and collect what they write to standard output and standard error.

The test file defines a subroutine called runperl( ) to abstract away and encapsulate all of the IPC::Run code. It calls run( ) with four arguments. The first argument is an array reference of the program to run ”here always $^X ”and its command-line options. The other arguments are references to three scalar variables to use for the launched program's STDIN , STDOUT , and STDERR handles. runperl( ) returns only the last two handles, which IPC::Run has helpfully connected to the output of the program.


Note: None ofthe tests yet need to pass anything to the launched program, so returning $in is useless .

Each set of tests starts by calling runperl( ) with the arguments to use when running Perl. The first run performs the equivalent of:

 $  perl -v  This is perl, v5.8.6 built for powerpc-linux          Copyright 1987-2004, Larry Wall          Perl may be copied only under the terms of either the Artistic License or the GNU  General Public License, which may be found in the Perl 5 source kit.          Complete documentation for Perl, including FAQ lists, should be found on     this system using 'man perl' or 'perldoc perl'.  If you have access to the     Internet, point your browser at http://www.perl.org/, the Perl Home Page. 

The tests check to see that the entire message goes out to standard output, with nothing going to standard error.

The second set of tests uses Perl's -V , or verbose, flag to display an even longer version message, which includes information about the compile-time characteristics of Perl as well as the contents of @INC .

Finally, the last set of tests exercise Perl's handling of an error, specifically leaving the sigil off of a variable. This test is equivalent to the one-liner:


Note: Try perl -V yourself. It's a lot of output .
 $  perl -e "x++"  Can't modify constant item in postincrement (++) at -e line 1, near "x++"     Execution of -e aborted due to compilation errors. 

All of this output should go to standard error, not standard output. The final test in this set ensures that.

What about...

Q:

Are there any modules that integrate this with Test::Builder for me?

A:

Test::Cmd and Test::Cmd::Common have many features, but they also have complex interfaces. They may work best for large or complicated test suites.



Perl Testing. A Developer's Notebook
Perl Testing: A Developers Notebook
ISBN: 0596100922
EAN: 2147483647
Year: 2003
Pages: 107

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net