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

In my lastnode I made reference to a forum system I was working on and asked for suggestions on implementing it. Of course, lots of people chimed in with the common mantra "Uses Tests!". My problem is now simply "How do I test such a beast?".

I've read the introduction to testing by chromatic and several other articles, and I think I have a fairly good idea as to what the general process of testing calls for.

My problem is that I can't seem to visualize a way to apply the tests to something like a forum. I can fairly easily visualize the tests for something simple, like a small library that exports a few functions, perhaps to perform math operations. I.e. is(MyLib::square(2),4) but how would I test say, the function that accumulates data to output in a template? Or even the method that outputs a template? Or perhaps the method that queries user data from a database?

Replies are listed 'Best First'.
Re: Test Suite for a forum?
by adrianh (Chancellor) on Jul 05, 2003 at 16:45 UTC

    Short answer: Think about what you want your forum code to do, then test that it does it :-)

    Slightly more useful answer...

    Before you write any code think about the requirement you're trying to meet, write a test for that requirement, then write some code to make the test pass.

    For example, if your forum consists of a number of named boards you need to create them - so write a test for board creation:

    isa_ok( Forum::Board->new(name => 'testboard'), 'Forum::Board' );

    Run the test. It fails. Now go write the code to make a board. You know when you've finished because the test will pass.

    Next you might need to get the name of an existing board, so write a test:

    is( Forum::Board->new(name => 'testboard')->name, 'testboard');

    Write code until test passes.

    Repeat the test/code cycle until all the module does all you want it to do.

    Never write code without a failing test. That way you build up your test suite as you go and end up with very good test coverage of your codebase.


    If something looks too complicated to test break it down into smaller chunks. For example, you have a code that takes various parameters and passes them to a template to display to the user.

    At the simplest level you could pass known parameters and look at the output and compare it with the output you want. Either as an exact string match, or by checking that the important bits are in the output string with a set of regexps. Gnarly.

    However, you could also separate it into two different tests:

    1. Am I generating the correct parameters for the template
    2. Is the template generating the correct output from the parameters

    Instead of testing both together, test each individually.

    1. Use a mock object for the template to make sure that the correct parameters are passed.
    2. Pass known parameters to the template to make sure that the correct output is produced.

    This way you ensure that your unit tests really are unit tests - and you're only testing one component at a time.

    I find that thinking "I can't test that" is usually a code smell. It indicates that there is a problem with my code and something is too tightly coupled to something else.


    When you get to doing acceptance testing it's probably simplest to just drive the application with something like WWW::Mechanize. You might find Unit Testing Generated HTML of interest too.

    Hopefully this makes some vague sort of sense :-)

Re: Test Suite for a forum?
by Corion (Patriarch) on Jul 05, 2003 at 16:11 UTC

    For my module CGI::Wiki::Simple, I have two kinds of tests - one kind that tests the basic functionality of every routine, throwing different inputs at it and looking that it gets the expected outputs. The other kind are end-to-end tests that set up a fake CGI request, let the wiki run, and look at the database and/or at the output of the program, to see if happened what was expected.

    This second kind of test is not easy to write as it has to be adapted every time you make a change in the output format, so I suggest that you use a different set of templates for testing - a simple line-based layout will be good for easy difference testing.

    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
Re: Test Suite for a forum?
by grantm (Parson) on Jul 06, 2003 at 06:30 UTC

    I concur with Corion that you need low-level tests to make sure each routine does what it should as well as end-to-end tests to make sure the pieces come together as you expect. For the latter, you might want to look into Apache::Test for which there is a tutorial here.

    When I've been using Apache::Test recently for end-to-end testing, I've found it useful at times to override the final presentation phase of my web application. Instead of returning a text/html page with nicely formatted results, I return a text/plain response containing a YAML dump of the application's internal state. Obviously you also need to test that the formatted results work too, but a state dump makes it very easy to test actual vs expected results for a wide range of input values.

Re: Test Suite for a forum?
by mvc (Scribe) on Jul 05, 2003 at 22:29 UTC