Ovid has asked for the wisdom of the Perl Monks concerning the following question:

So often you open up a test suite and see 20 test programs starting with something like this:

use Test::More tests => 23; use Test::Differences; use Test::Exception;

That's awfully repetitive and if you have a standard set of testing tools, that gets annoying. Instead, I'd like to do something like this:

  use My::Tests tests => 20;

That would incorporate all of the above and look like this:

package My::Tests; use Test::Custom qw( Test::More Test::Differences Test::Exception ); 1;

Of course, you'd have to have importing facilities and "conditional" loading:

package My::Tests; use Test::Custom qw( Test::More Test::Differences ), 'Test::SomethingOrOther' => [ 'bulges_ok' ]; Test::Custom->add('Test::NoWarnings') if $some_condition; 1;

The question I'm trying to figure out is the best way to implement this. I could have Test::Custom (better names welcome) build something like this:

eval <<"END"; package $calling_package; use Test::More @test_more_imports; use Test::Exception @test_exception_imports; use Test::Differences @test_differences_imports; END if ( my $error = $@ ) { ... }

However, I just *know* there are problems with this, but I can't think for the life of me what they might be. Does that seem sane to folks? Am I overlooking something blindingly obvious?

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re: Best Way to Make a Custom Testing Module
by rhesa (Vicar) on Mar 30, 2007 at 12:12 UTC
    Sounds like you want what ToolSet offers. Looking at the ToolSet source, I see that it also uses eval, only in a more controlled way. I think you may be alright with your approach.

      Ooh, baby! That's my new favorite module of the week.

      cat >~/.sig </dev/interesting
Re: Best Way to Make a Custom Testing Module
by Moron (Curate) on Mar 30, 2007 at 11:21 UTC
    A testset is naturally a container class rather than a class of individual tests such as Test::Class. For example:
    use Test::Class; # for the individual tests package TestSet; sub new { my $self = []; my $class = shift; bless $self; @_ and $self -> addtest( @_ ); return $self, $class; } sub addtest { my $self = shift; push @$self, @_; } etc. package main; my $test = Test::Class -> new(); my $testset = TestSet -> new( $test ); etc.

    -M

    Free your mind

Re: Best Way to Make a Custom Testing Module
by Herkum (Parson) on Mar 30, 2007 at 10:52 UTC

    Can you use the if statement with your use declaration instead of eval?

    I am not sure if that will help or not because I don't know the specifics, I am just offering a suggestion here.

Re: Best Way to Make a Custom Testing Module
by ww (Archbishop) on Mar 30, 2007 at 14:28 UTC
    Name thoughts...
    s/Test::Custom/Test::TestSet/
    or
    s/Test::Custom/Test::MultiTests/
    or
    s/Test::Custom/Test::GroupTests/

    These are, of course, just one monk's notion of more intuitive naming, as my immediate thought on reading Test::Custom was of a module designed to tweak ("customize" some existing test module).

Templates Fix Part of the Problem
by doom (Deacon) on Apr 02, 2007 at 20:00 UTC
    So often you open up a test suite and see 20 test programs starting with something like this:
    use Test::More tests => 23;
    use Test::Differences;
    use Test::Exception;
    Is the difficulty just that it makes for boring reading, or are you annoyed at the amount of typing? The way I deal with this sort of thing these days is to use code generation templates. Myself I work with emacs, and the template.el package (along with a package I wrote myself, perlnow.el). I keep meaning to look into ways of doing this with, say, Template::Toolkit, (that would be more likely to be more widely popular with perl programmers).

    The advantage of using a template to generate such stuff is that it places a little more of the burden on the code author (rather than creating One More Custom Module that someone reading the code needs to understand). I also like the way it makes it a little easier to start with a standard way of doing things, and then diverge from it if there's a reason to: you can just mutate the code the template inserted at will, without fear of effecting anything else that uses the template. And when you find a trick that you want to use everywhere, the changes to the templates only effect new code, you don't need to re-test all the existing code to look for accidental breakage.