From time to time I'll work on a code base that's basically a pile of individual scripts. The process of converting it to a modularized system can take some time, technically as well as socially. Meanwhile, I have to get work done. And for me getting work done requires writing tests.
But if it's a pile of scripts, where do you put them? And with no build structure, how do you run them? Rather than having to decide between using a single file OR writing tests, I decided to embed the tests in the scripts themselves. Observe.
sub selftest { my @test_functions = get_test_functions();
for my $function (sort { lc $a cmp lc $b } @test_functions) { no strict 'refs'; print "# Running $function\n"; &{$function}; } }
sub get_test_functions { my $package = shift || __PACKAGE__;
# Load the test functions after __END__ eval join '', ;
no strict 'refs';
return # Select only those which are subroutines grep { defined &{$_} }
# Find the ones named test_* grep /^test_/,
# Get all the symbols in the package keys %{$package."::"}; }
use Getopt::Long;
sub main { my %options; GetOptions( \%options, "test", );
if( $options{test} ) { selftest(); exit; }
... rest of the code here ... }
main();
__END__ # These tests will be compiled and run when --test is given
use strict; use warnings;
use Test::More 'no_plan';
sub test_the_tests { pass("The tests run!"); }
Re:Similar...
schwern on 2008-04-24T19:29:42
What an amazing coincidence. I still need to get POD example testing back into Test::Inline 2.
Test::Inline and selftest are similar in that they both follow the idea of embedding the tests into the code being tested. Test::Inline focuses on putting the test as close to the code being tested as possible, but it requires scaffolding to run those tests. selftest focuses on being able to deliver a single, self-contained package.
I think I'll release it as Test::Yourself. What do you think?
Re:Similar...
Alias on 2008-04-25T01:47:53
Test::Inline (both Schwern's original Pod::Tests and my replacement) aren't really suitable for this situation, as he's applying it to standalone scripts rather than distributions.