Hello Monks!
I have a script in my distribution that allows convenient CLI access to my library. It's handy, but it's not the main focus of my distribution. Still, I would like to get unit test coverage for it if I can.
The basic skeleton of my script is below, but it is built around the "modulino" approach of main(@ARGV) unless caller suggested by blogs such as this one (Gabor Szabo). How can I add unit tests for things like:
Test::Output would get me part of the way there, but anything that actually exits, such as pod2usage, exits the entire test script, which causes a failure. I could actually execute the script, but that isn't much of a "unit" test anymore and also defeats the purpose of the "modulino" style of unit testing scripts like this, and doing that portably would be tricky.
(Portability is a key requirement here.)
All of the searching I've done seems to stop at "shove everything into a sub, and unit test that", but I've not been able to find any useful examples that actually dive into the specifics of common tasks like pod2usage, anything that calls exit for any reason, scripts that read from standard input, etc.
My script is handy and worthy of distribution, but it's still just a thin wrapper around my library. If I were to skip unit tests for those things, my script would have barely any useful unit tests, and then I might be inclined to not include it in the distribution at all.
How would you unit test something like this? I also obviously do my own integration testing before every release, but that serves a different purpose.
#!/usr/bin/env perl use 5.010; use strict; use warnings; my $VERSION = '1.00'; use Getopt::Long 'GetOptionsFromArray'; use Pod::Usage; main(@ARGV) unless caller; sub main { my $ARGV = \@_; my %args = ( help => sub { pod2usage -verbose => 1, -exitval => 0 }, version => sub { say "my_script version $VERSION\n"; exit }, ); GetOptionsFromArray($ARGV, \%args, qw<host=s port=i password=s help version> ) or pod2usage(2); if (@ARGV) { do_something($_) for @ARGV; } else { while (<STDIN>) { chomp; do_something($_) } } } sub do_something { say "do_something: $_[0]"; }
In reply to Portably unit testing scripts by wanna_code_perl
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |