SYNOPSIS

   use A::Module qw/or two!/;
   use Test::TableDriven (
     foo => { input   => 'expected output',
              another => 'test',
            },

     bar => [[some => 'more tests'],
             [that => 'run in order'],
             [refs => [qw/also work/]],
             [[qw/this is also possible/] => { and => 'it works' }],
            ],
   );

   runtests;

   sub foo {
      my $in  = shift;
      my $out = ...;
      return $out;
   }

   sub bar { same as foo }

DESCRIPTION

Writing table-driven tests is usually a good idea. Adding a test case doesn't require adding code, so it's easy to avoid fucking up the other tests. However, actually going from a table of tests to a test that runs is non-trivial.

\*(C`Test::TableDriven\*(C' makes writing the test drivers trivial. You simply define your test cases and write a function that turns the input data into output data to compare against. \*(C`Test::TableDriven\*(C' will compute how many tests need to be run, and then run the tests.

Concentrate on your data and what you're testing, not \*(C`plan tests =\*(C' scalar keys %test_cases> and a big foreach loop.

WHAT DO I DO

Start by using the modules that you need for your tests:

use strict; use warnings; use String::Length; # the module you're testing

Then write some code to test the module:

sub strlen { my $in = shift; my $out = String::Length->strlen($in); return $out; }

This \*(C`strlen\*(C' function will accept a test case (as $in) and turns it into something to compare against your test cases:

Oh yeah, you need some test cases:

use Test::TableDriven ( strlen => { foo => 3, bar => 3, ..., }, );

And you'll want those test to run somehow:

runtests;

Now execute the test file. The output will look like:

1..2 ok 1 - strlen: bar => 3 ok 2 - strlen: foo => 3

Add another test case:

strlen => { foo => 3, bar => 3, quux => 4, ..., },

And your test still works:

1..3 ok 1 - strlen: bar => 3 ok 2 - strlen: quux => 4 ok 3 - strlen: foo => 3

Yay.

DETAILS

I'm not in a prose-generation mood right now, so here's a list of things to keep in mind:

  • Don't forget to \*(C`runtests\*(C'. Just loading the module doesn't do a whole lot.

  • If a subtest is not a subroutine name in the current package, runtests will die.

  • If a subtest definition is a hashref, the tests won't be run in order. If it's an arrayref of arrayrefs, then the tests are run in order.

  • If a test case \*(L"expects\*(R" a reference, \*(C`is_deeply\*(C' is used to compare the expected result and what your test returned. If it's just a string, \*(C`is\*(C' is used.

  • Feel free to use \*(C`Test::More::diag\*(C' and friends, if you like.

  • Don't print to \s-1STDOUT\s0.

  • Especially don't print \s-1TAP\s0 to \s-1STDOUT\s0 :)

EXPORT

runtests

Run the tests. Only call this once.

BUGS

Report them to \s-1RT\s0, or patch them against the git repository at:

git clone git://git.jrock.us/Test-TableDriven

(or <http://git.jrock.us/>).

AUTHOR

Jonathan Rockway \*(C`<jrockway AT cpan.org>\*(C'.

COPYRIGHT

This module is copyright (c) 2007 Jonathan Rockway. You may use, modify, and redistribute it under the same terms as Perl itself.