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

In an effort to improve testing on my modules, I am using Test::More and re-writing all of the tests. However, I am running into a small problem.

If I add Test::More to the Makefile.PL, this creates a dependency upon that module, that I would prefer it not to have. However, trying to write the test so that it if Test::More is installed it runs those tests, and runs the normal test.pl file if Test::More is not present, is giving me a headache. How would I go about implementing something like this? My attempt follows:
eval{ require Test::More; }; if(@$){ BEGIN { $| = 1; print "1..11\n"; } END {print "not ok 1\n" unless $loaded;} use Games::QuizTaker; $loaded = 1; print"Loaded ................. ok 1\n"; $Q1=Games::QuizTaker->new(FileName=>"sampleqa",Score=>1); if($$Q1{_FileName} eq "sampleqa"){ print"{_FileName} ............ ok 2\n"; }else{ print"{_FileName} ............ not ok 2\n"; } if($$Q1{_Delimiter} eq "|"){ print"{_Delimiter} ........... ok 3\n"; }else{ print"{_Delimiter} ........... not ok 3\n"; } $Q2=Games::QuizTaker->new(FileName=>"sample.csv",Delimiter=>","); if($$Q2{_Delimiter} eq ","){ print"{_Delimiter} init ...... ok 4\n"; }else{ print"{_Delimiter} init ...... not ok 4\n"; } my %hash=(); my $refhash=$Q1->load(\%hash); my $Num=keys %$refhash; if($Num == 9){ print"Load function .......... ok 5\n"; }else{ print"Load function .......... not ok 5\n"; } my($ref1,$ref2,$ref3,$ref4)=$Q1->generate(\%hash); my $num=keys %{$ref1}; if($num == 9){ print"Generate function ...... ok 6\n"; }else{ print"Generate function ...... not ok 6\n"; } my $V=$Q2->get_VERSION; if($V=~/^\d\.\d{1,3}/){ print"Version function ....... ok 7\n"; }else{ print"Version function ....... not ok 7\n"; } my $Q3=Games::QuizTaker->new(FileName=>"sample.csv",Delimiter=>",",Ans +wer_Delimi ter=>"x"); my $del=$Q3->get_Answer_Delimiter; if($del eq "x"){ print"Answer_Delimiter init .. ok 8\n"; }else{ print"Answer_Delimiter init .. not ok 8\n"; } my $Max=$Q3->get_Max_Questions; if($Max == 0){ print"Max_Questions init ..... ok 9\n"; }else{ print"Max_Questions init ..... not ok\n"; } my $Final=$Q3->get_Score; if(! defined $Final) { print"Final Score default .... ok 10\n"; }else{ print"Final Score default .... not ok 10\n"; } my $Final2=$Q1->get_Score; if(defined $Final2){ print"Final Score set ........ ok 11\n"; }else{ print"Final Score set ........ not ok 11\n"; } }else{ require Test::More; BEGIN { use_ok('Games::QuizTaker', 'Games::QuizTaker loaded'); } $Q1=Games::QuizTaker->new(FileName=>"sampleqa",Score=>1); ok($$Q1{_FileName} eq "sampleqa", 'FileName set'); ok($$Q1{_Delimiter} eq "|", 'Default delimiter set'); $Q2=Games::QuizTaker->new(FileName=>"sample.csv",Delimiter=>","); ok($$Q2{_Delimiter} eq ",",'File Delimiter set'); my %hash=(); my $refhash=$Q1->load(\%hash); my $Num=keys %$refhash; ok($Num == 9,'Load Function'); my($ref1,$ref2,$ref3,$ref4)=$Q1->generate(\%hash); my $num=keys %{$ref1}; ok($num == 9,'Generate Function'); my $V=$Q2->get_VERSION; ok($V=~/^\d\.\d{1,3}/, 'VERSION Function'); my $Q3=Games::QuizTaker->new(FileName=>"sample.csv",Delimiter=>",",A +nswer_Delimiter=>"x"); my $del=$Q3->get_Answer_Delimiter; ok($del eq "x", 'Answer_Delimiter init'); my $Max=$Q3->get_Max_Questions; ok($Max == 0,'Max Questions init'); my $Final=$Q3->get_Score; ok(! defined $Final,'Default Final Score'); my $Final2=$Q1->get_Score; ok(defined $Final2, 'Set Final Score'); }

TStanley
--------
The only thing necessary for the triumph of evil is for good men to do nothing -- Edmund Burke

Replies are listed 'Best First'.
Re: Working with Test::More
by Abigail-II (Bishop) on Oct 29, 2003 at 15:38 UTC
    If I add Test::More to the Makefile.PL, this creates a dependency upon that module, that I would prefer it not to have. However, trying to write the test so that it if Test::More is installed it runs those tests, and runs the normal test.pl file if Test::More is not present, is giving me a headache.
    If you decide to write 'regular' tests in the case Test::More isn't present, why bother writing Test::More tests at all? Test::More is there to make it easier to write test. Writing tests twice in such a way that it uses Test::More if Test::More is present, and do it the old fashion way if Test::More isn't serves no purpose.

    Besides, the most used functionality of Test::More (subs like 'ok', 'is', 'isnt') is easily written, and can be included in the test file(s) so you have no dependencies.

    Abigail

Re: Working with Test::More
by adrianh (Chancellor) on Oct 29, 2003 at 16:36 UTC

    Test::More has been core since Perl v5.007003. So, unless you are worrying about supporting people before that version I would just dump your old tests and use Test::More.

    One other option would be to include Test::More et al in your distributions t/lib and use it from there. Personally I dislike this way of doing things since you have problems when modules are updated.

      One other option would be to include Test::More et al in your distributions t/lib and use it from there. Personally I dislike this way of doing things since you have problems when modules are updated.

      I would agree for just about any module but Test::More. However, in this case I think that including Test::More with your distribution is entirely reasonable.

      • Any new features in a later version are unneeded for a given test suite.
      • Bugfixes will mostly result in things passing that failed with the older version, and you'll discover those in your test suite so you'll never release with them anyway.
      • Bugfixes that result in things failing that previously passed would be nice to have. But think of how this happens -- people who upgrade to the latest Test::More will suddenly see your (unchanged) module start failing, which means you have at the very least a bug in your test and should issue a new release anyway. And the new release will contain the updated Test::More.
      • The final reason I can think of for upgrading is security fixes, and while I can imagine Test::More (well, Test::Builder really) creating temporary files insecurely or something like that, I just don't think the risk is that high. For this reason alone, however, you should probably use the system Test::More, if it exists, in favor of the bundled one.

        It's a personal call of course. However, for me the potential pain of dealing with the issues you raised (and others) outweigh the pain of getting the user to install a module that is almost certainly installed already.

        As ever YMMV :-)

      Schwern and I used to recommend that people bundle Test::More, but now it's easier just to add a dependency. Enough modules depend on it already that it's likely already installed. (Besides that, it's been in core for two — almost three — stable releases. At some point, people should really start using new features of software if we're supposed to keep adding them.)

Re: Working with Test::More
by jZed (Prior) on Oct 29, 2003 at 16:13 UTC
    Well, it seems like there are several ways to go. Here's one. Create a module that exports plan() and ok() by itself (i.e. fakes them without using Test::More). Then distribute that module along with the test and put the code below at the top of the test. This way you only write your tests once, rather than two versions of all tests like you have.
    BEGIN { eval { use Test::More; }; if ($@) { use myModuleThatBehavesLikeTestMore; } }
      What is the point of this? Why is this preferable over:
      use myModuleThatBehavesLikeTestMore;

      It's not saving you to write code. It's not saving disk space. What's the gain here?

      Abigail

        There's a big gain over the OP's original version. As for a gain over just ignoring Test::More, I can think of two (neither of which really amounts to a hill of beans): 1) you could test your own test by making sure that it produced the same results with Test::More and myMTBLikeTestMore and 2) you could upload myMTBLTestMore to CPAN so others could use it and then a hilarious amount of recursiveness could occur.

        Seriously though, it seems like if Test::More isn't going to be in the core (is it?), then people ought to be able to distribute it with their modules and have tests start with pseudocode( if there's a more recent Test::More locally, use it, otherwise use this one I've distributed with my module).

Re: Working with Test::More
by TStanley (Canon) on Oct 29, 2003 at 23:28 UTC
    Thank you all for your suggestions. I have decided to go ahead and include a dependency for Test::More in the Makefile.PL . And as I write this, my three modules are listed in the CPAN Nodelet after I uploaded them with the Test::More dependency.

    TStanley
    --------
    The only thing necessary for the triumph of evil is for good men to do nothing -- Edmund Burke