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

Hi all, I have been handed responsibility of a perl application, it has some *ok* documentation, uses CVS and seems to work as it should.

However what it is suffering from is bugs being introduced, bugs being fixed and the same bug coming back again. I have to put my hand up and admit that I have never used any of the perl testing framework previously, however always seeking to improve and stabalise the application I am sure most here will agree introducing a testing suite to the application and would like to ask others advice/experiences in patching in testing *after* an application is built.

Currently all the applications modules sit in a fixed directory sturcture, say /var/application/modules/, where all scripts/CGI's which are using the modules will simply have a use lib '/var/application/modules/', then followed by a standard use statement.

The reason why I mention this I am also new to generating the stub modules using h2xs, and anyway seems somewhat late for this but what I would like to achieve is pretty much what h2xs generates.

What I think is needed is for every 'module' there is an associated test script, which tests a modules unique methods. Of course the modules all interact with each other, so there also needs to be test scripts which test the relationships between the various modules.

Now what I believe would be the correct way forward, would be to have a single Makefile.PL which when ran would generate a Makefile which would effectively allow all the tests against all of the modules at once. For instance using h2xs, (and maybe I just dont understand it) I could create a new modules, then go into its directory do a perl Makefile.PL;make;make test, and this would run *that* modules test scripts in tthe /t/ dir. However I want to have a Makefile.PL which would do this process for *all* of the relevant modules at once, so the make test would perform all the tests. Then I believe that doing a make install (subject to the tests being completed ok) would build the modules in the standard libraries thus doing away with the use lib on the production servers.

So is above a feasible idea, how do I go about plugging in Makefile facilities after the code is written ? I have done some test scripts already, however is there any advice anyone can give a testing newbie on creating good test cases ?

And if I am doing this the wrong way guidance would be welcome

Replies are listed 'Best First'.
Re: Testing a already built application
by brian_d_foy (Abbot) on Feb 15, 2005 at 06:25 UTC

    You don't need to make your distribution look like the structure that h2xs gives you, so stop worrying about h2xs. You can look at other utilities, like Module::Starter. You might want to create a fake distro just to see what it does and how it works. In the same way, you don't need a Makefile.PL to test, although it does help. You want to get there eventually, but if testing is more important at the moment, you can skip it for now.

    You can use the prove(1) function that comes with Test::Harness. You tell prove where to find the modules, and which test files to run, and it handles the rest. If you write the tests first, this is the quickest way to get going.

    I suggest that you start off so that you can move towards a Makefile.PL (or a Build.PL if you want to use Module::Build instead]. Put all of your tests in a directory named t since that's where Makefile.PL and Build.PL look for them by default.

    As for writing the tests, I like to make a lot of small test files, usually one per function in the public interface at least. That's mostly a matter of taste. With prove, you can limit your tests to just the files you want, so if you have a lot of test files with a small number of tests, you can break down your testing easily. With only a couple of test files that each have a large number of tests, you might have to sit through a lot of tests that you don't care about at the moment.

    Once you are ready to create the Makefile.PL, I suggest you look at a couple on CPAN and find one that looks simple and close to what you want, then copy it. You'll be able to tell Makefile.PL where to find the modules (they don't have to be in a lib/ directory), where to put other files like executables, and so on. The ExtUtils::MakeMaker documentation has all of the details, and don't let it scare you off in the first two minutes. ExtUtils::MakeMaker::Tutorial will help too, as will perlmodstyle and perlnewmod.

    As for creating good test cases, look around and you'll find a lot of advice on testing. Good luck :)

    --
    brian d foy <bdfoy@cpan.org>
Re: Testing a already built application
by Zaxo (Archbishop) on Feb 15, 2005 at 06:14 UTC

    You will want Test::Harness and Test::More. You probably already have them.

    The easiest way to get started with those modules is to just examine the t/ directory of some CPAN module distributions. After that, take a look at the Test::More perldocs.

    A recurrent bug can be swatted for good by turning the code fragment which triggers it into a short series of tests. Just compare the expected values to the actual ones for known input values. The test suite will then check for regressions each time it is run.

    A Makefile.PL is a good thing to have, and not just for running the test suite, but you can also just call the runtests function of Test::Harness, $ perl -MTest::Harness -e'runtests @ARGV' t/*.t

    After Compline,
    Zaxo

Re: Testing a already built application
by dragonchild (Archbishop) on Feb 15, 2005 at 13:54 UTC
Re: Testing a already built application
by geektron (Curate) on Feb 15, 2005 at 08:47 UTC
    another way to go about this (without h2xs), would be to use ExtUtils::ModuleMaker to create the Makefile.PL and the stubs that h2xs would (without a few of the gotchas of h2xs), and make any needed changes to the Makefile.PL (and the MANIFEST file, if needed).

    I've been creating a fake distro with ExtUtils::ModuleMaker lately, and have been relatively pleased with the results. I haven't completely translated the fake distro into my existing codebase yet, but that's my next step.

Re: Testing a already built application
by cbrandtbuffalo (Deacon) on Feb 16, 2005 at 00:48 UTC
    Based on the info you provided, I suggest starting with some interface testing. At this point, your work/reward ratio will be quite high because you are already experiencing "fix one, break two" and some regression.

    Most of the suggestions so far have focussed on standard Perl testing, which is generally unit testing. I'll offer a different option. You mention CGI scripts, so you could build tests to excercise the interface. Take notes on how you have found previous bugs through the browser. Then you can look into automating that sequence using WWW::Mechanize and Test::WWW:Mechanize.

    We did this for a large amount of existing web code because in addition to not having tests, much of our older code wasn't very 'testable.' Creating new unit tests would have involved a lot of refactoring because the code wasn't modular. Building tests of the interface was much easier and effective.

    Then, moving forward, consider all of the advice above. Each time you add code or fix a bug, make the code very modular and testable and write tests for it. That way you will be in good shape moving forward. If you take this approach when you fix bugs, your 'buggy' code will start to have much better coverage and you'll experience many fewer bugs.

      Thanks all who contributed,

      A wealth of information to look into, and all of it seems very relevant to what I am trying to achieve. Am sure many more questions on testing to come, thanks for now.