Refactor larger test suite


Now that we have this tool in place it is time to start to enlarge our test suite. After all three tests are not enough. As we are adding more and more tests we can recognize again that there is the data part of the tests that are changing and the code part which is repeating. This is a good time to refactor our code again. We take the data and move it to a data structure. The code then can go over this data structure and execute each unit on its own.

examples/test-simple/tests/t21.pl
use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/../lib";
use MySimpleCalc qw(sum);

my @tests = (
    [ 1,  1,  2    ],
    [ 2,  2,  4    ],
    [ 2,  2,  2, 6 ],
    [ 3,  3,  6    ],
    [-1, -1, -2    ],
    [ 1, -1,  0    ],
);

use Test::Simple tests => 6;

foreach my $t (@tests) {
    my $expected = pop @$t;
    my $real     = sum(@$t);
    my $name     = join " + ", @$t;

    ok( $real == $expected, $name );
}

Output:


1..6
ok 1 - 1 + 1
ok 2 - 2 + 2
not ok 3 - 2 + 2 + 2

#   Failed test '2 + 2 + 2'
#   at examples/perl/tests/t21.pl line 24.
ok 4 - 3 + 3
ok 5 - -1 + -1
ok 6 - 1 + -1
# Looks like you failed 1 test of 6.

For every unit we created an array reference where the last element is the expected output. Anything before that is the list of parameters. We then created an array (@tests) of all these units.

In the code we loop over all the units, $t holding the current unit, and then extract the expected output using pop. The remaining values are the parameters to the test. We also generate the name of the test from the input values.

There is a small problem though. When you add a new test to the array, you also have to remember to update the tests => 6 line.

There are a number of solution to this problem