[Pdx-pm] testing CLI option parsing with YAML

Randall Hansen randall at sonofhans.net
Wed Aug 24 16:32:15 PDT 2005


folks ~

i just did something mildly cool and useful and thought i would share  
it.

i have a script which accepts command-line arguments with  
Getopt::Long.  there's logic in the option parsing which i need to  
test (e.g. some options conflict).  the parsing code is in an object,  
and the incoming arguments only set object properties, they don't  
produce immediate output.

my solution was to create a tiny perl script on the fly, running only  
the option parsing code.  i run this script repeatedly with different  
arguments.  it parses those arguments and dumps the resulting object  
properties to STDOUT using YAML.  the test script captures this YAML,  
turns it into a data structure, and returns it to be tested.

here's the function:

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# constructs and runs perl code which uses the module, then dumps
# the data structure returned.  we parse this and return it.
sub get_data {
     my( $args ) = @_;

     $args ||= '';
     my $perl = <<'EOT';
     use strict;
     use warnings;
     use YAML;
     use nemos::Populate;

     my $p = nemos::Populate->new;
     print Dump $p->get_options;
EOT

     # double-dash tells perl to stop parsing arguments; all
     # arguments after that are passed to the script
     # 2>&1 captures standard error as well
     my $command = "perl -Ilib -e '$perl' -- $args 2>&1";
     my $results = `$command`;

     my $yaml;
     eval{ $yaml = Load $results };
     # return raw output if YAML can't serialize the result
     return $@ ? $results : $yaml;
}

sample tests:
     # these arguments return raw output only
     $data = get_data( '--full --oid', 0 );
     like( $data, qr/ERROR: Option 'full' precludes 'oid'./);

     # these arguments return data serialized by YAML
     $data = get_data( '--oid 123 --ip 1.2.3.4' );
     is( keys %$data, 2 );
     is_deeply( $data->{ oid }, [ 123 ]);
     is_deeply( $data->{ ip }, [ '1.2.3.4' ]);

r



More information about the Pdx-pm-list mailing list