I am currently working on a module with an really ugly testsuite (written by me of course ;) ). Refactoring a testsuite is no fun, but at least I want to remove all duplicated code. Currently, every single testfile looks like this:
#!perl -T use strict; use warnings; BEGIN { use lib 't'; use MyTestHelper; use Test::More; # check some external dependencies (programs and non # CPAN modules my ($skip,$msg) = MyTestHelper::skip_all(); plan skip_all => $msg if $skip; } our %features = ( A => 72, B => 148, C => 43, D => 34, ); my $number_tests; foreach ( keys %features ) { $number_tests += $features{$_}; } plan tests => $number_tests; use English qw( -no_match_vars ); use Scalar::Util qw/refadr/; use Data::Dumper; use MyModule; my $obj = MyModule->new(); FEATURE: foreach my $feature ( sort keys %features ) { SKIP: { if ( $obj->does_not_like($feature) { skip "Feature not available", $features{$feature}; } # FINALLY, the tests ... } }
Which is much code for boring stuff. I need this features feature because I test several back-ends (the features in the test). If a back-end is not available, we can skip all tests of this back-end. Another problem is that it only checks the absolute number of tests. So the test would pass if feature A had 73 tests and feature B 147 (which is not so far-fetched than you might think). I want a simple framework like:
package MyTestFramework; use base 'Test::SimpleFramework'; sub init { my ( $self ) = @_; $self->set_strict(1); $self->set_warnings(1); $self->export({ 'Scalar::Util' => 'refaddr', 'English' => '-no_match_vars', 'Data::Dumper' => undef, 'MyModule' => undef, }); $self->dependencies({ 'lftp binary in path' => $self->in_path('lftp'), 'non-CPAN module' => $self->in_inc('Non::Cpan'), }); } our @EXPORT = qw( delete_temporary_files ); sub delete_temporary_files { foreach my $file ( <t/tmp/*> ) { my ( $filename ) = $file =~ m{\A t/tmp/ ([\d\w\.\-]+) \z}xms; unlink "t/tmp/$filename"; } }
And now, my testfiles would look like this:
#perl -T BEGIN{ use lib 't'; }; use MyTestFramework; # skips all tests if one dependency was't found check_dependencies(); register_features({ A => 72, B => 148, C => 43, D => 34, }); my $obj = MyModule->new(); while (my $feature = next_feature) { skip_feature if $obj->does_not_like($feature->name); # the tests ... # dies if number of tests for feature is not correct } delete_temporary_files();
A little research on CPAN revealed, that the features of Test::SimpleFramework are a mixture of Test::Class, Test::Block (dying if number of tests of a feature is not correct) and ToolSet, although my unexperienced eyes don't see a simple solution how these three modules could be combined. I am not sure whether the world needs yet another Test::* module, but how would you refactor my old code to get a similar functionality? If it is avoidable to introduce dependencies just for the testsuite, it would be a big plus.

Or would you like to see something like this on CPAN?

UPDATE: in my tests, "features" is "backends". "features" is probably the wrong generalization. What I actually do is to test different implementations of an interface API.


In reply to A simple test framework by lima1

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.