Day 4: Testing

Perl authors have a long tradition of shipping test cases with their modules, and in Perl 6 we plan to continue with that nice tradition.

And testing is very easy. The traditional perlish way is to print data in the Test Anything Protocol. But you don’t have to do that yourself, you can use a module for that.

Assume you have written a nice factorial function

 sub fac(Int $n) {
     [*] 1..$n
 }

Currently it doesn’t matter for us how that function works – we want to find out if it does. So let’s test it:

 use v6;

 sub fac(Int $n) {
     [*] 1..$n
 }

 use Test;
 plan 6;

 is fac(0), 1,  'fac(0) works';
 is fac(1), 1,  'fac(1) works';
 is fac(2), 2,  'fac(2) works';
 is fac(3), 6,  'fac(3) works';
 is fac(4), 24, 'fac(4) works';

 dies_ok { fac('oh noes i am a string') }, 'Can only call it with ints';

And let’s run it:

 $ perl6 fac-test.pl
 1..6
 ok 1 - fac(0) works
 ok 2 - fac(1) works
 ok 3 - fac(2) works
 ok 4 - fac(3) works
 ok 5 - fac(4) works
 ok 6 - Can only call it with ints

In detail: use Test; loads the testing module, plan 6; declares that we plan to run six tests. Then five lines of the pattern is $got, $expected, $description follow. is() does string comparison, but since integers always stringify the same way, that’s fine.

Finally with dies_ok { $some_code }, $description we test that calling the function with a non-integer argument is a fatal error.

The output contains the test plan 1..6, followed by one line for each test. That starts with ok (or not ok if the test failed), the test number, space, dash, space and test description.

If you run more tests, you don’t want to look through every test output carefully, but you want a summary. The prove command from Perl 5 gives you such a summary:

 prove --exec perl6 fac-test.pl
 fac-test.pl .. ok
 All tests successful.
 Files=1, Tests=6, 11 wallclock secs ( 0.02 usr  0.00 sys + 10.26 cusr  0.17 csys = 10.45 CPU)
 Result: PASS

You can also put all your test files in a directory, let’s call it t/, and run prove recursively on all .t files in that dir:

 prove --exec perl6 -r t

Putting that line in your Makefile is also nice, so that you can just type
make test to run the tests.

10 thoughts on “Day 4: Testing

  1. Thanks, good one!

    What makes the script so slow? Is it the module-loading? Will the performance likely still be this bad in Rakudo*?

  2. Rakudo is just generally slow, because the focus is on features and correctness first, and speed later.

    That said I hope that there will be some improvements before Rakudo Star is released, and if the parrot developers manage to build a good JIT system on top of LLVM until then it might be quite a bit faster.

    1. To what extent Rakudo is slow? If Rakudo Start is intended to be a usable release, it must not be, say 1X~2X slower than perl 5?

    1. Well, it is, but only in newer versions of Test::Harness. At least 3.10 has the ‘–exec’ option. You might want to download a newer version from CPAN.

  3. To update the test code to run under the current Perl 6, you could change the last line of test code to the following:

    my $my_string = ‘oh noes i am a string’;
    dies-ok { fac($my_string) }, ‘Can only call it with ints’;

    Thanks so much for your years of work on Perl 6! Merry Christmas!

  4. Maybe WordPress doesn’t know abougt Perl6. Trying again with “Perl” formatting:

        my $my_string = 'oh noes i am a string';
        dies-ok { fac($my_string) }, 'Can only call it with ints';
    

Leave a reply to bened Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.