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.