Friday, August 24, 2007

Using Perl's Test::Simple and Test::More

Testing is simple. You are basically seeing if something is either true or false, usually comparing two values. That's pretty much it. It's that way on purpose.

There are two main modules for doing this: Test::More and Test::Simple.

I'd like to show you how to use them to write your own tests.

Test::Simple



Test::Simple is perfect in naming as it is simple and runs tests. Well, actually it only runs one test multiple times, if you choose to run it multiple times. It only has one subroutine, 'ok()', which will either evaluate an expression to true or false (pass or fail). Here is an example of using Test::Simple.

Here is the simple class we'll be testing (that just tests multiples [of 5 and 30]):

#!/usr/bin/perl
#
use strict;
use warnings;


package MultipleAsker;

sub new {
my ($class) = shift;
my $attrs = {};
bless ($attrs, $class);
return ($attrs);
}

# See if $what is a multiple of $number, return 1/0
sub _ofNumber {
my ($self, $number, $what) = @_;
my $ret = 0;
$ret = 1 if (($what % $number) == 0);
return ($ret);
}

sub ofFive {
my ($self, $what) = @_;
return ($self->_ofNumber(5, $what));
}

sub ofThirty {
my ($self, $what) = @_;
return ($self->_ofNumber(30, $what));
}

1;


See, the class is pretty simple. It just has two subroutines available: ofFive and ofThirty (_ofNumber is implied private).

Now we just need to test those two functions (and if new worked):

#!/usr/bin/perl
#
use strict;
use warnings;

use Test::Simple tests => 7;

use MultipleAsker;

my $ma = MultipleAsker->new();

# Test of new()
ok (defined($ma) && ref $ma eq 'MultipleAsker', 'new worked');

# Test ofFive()
ok ($ma->ofFive(24) == 0, '24 is not multiple of 5');
ok ($ma->ofFive(25) == 1, '25 is multiple of 5');
ok ($ma->ofFive(5) == 1, '5 is multiple of 5');

# Test ofThirty()
ok ($ma->ofThirty(34) == 0, '34 is not multiple of 30');
ok ($ma->ofThirty(120) == 1, '120 is multiple of 30');
ok ($ma->ofThirty(30) == 1, '30 is multiple of 30');


As you can see, only making use of the one function: ok. Notice 'test => 7'. This is how you tell Test::Simple how many tests you're going to run. You should know this when writing your code. Note that the second arguement (the test description) is purely optional.

Here is the output of the tests:

1..7
ok 1 - new worked
ok 2 - 24 is not multiple of 5
ok 3 - 25 is multiple of 5
ok 4 - 5 is multiple of 5
ok 5 - 34 is not multiple of 30
ok 6 - 120 is multiple of 30
ok 7 - 30 is multiple of 30


Pretty simple eh?! Yeah it is.
So, that seems pretty good, what more does Test::More offer me... other than 'more'?!

It offers you some more methods for testing, that are basically ok() under-the-hood, yet make your tests... erm more 'simple'. Yeah, it seems ironic, yet it isn't. It provides your methods of testing things so your first argument to ok() isn't huge for more complex things. It also helps with clarity.

Test::More



Let's go right into some code. Here is an example of using Test:More on the MultipleAsker class also:

#!/usr/bin/perl
#
use strict;
use warnings;

use Test::More tests => 8;

use_ok( 'MultipleAsker' ); # Easy to test importing the module

my $ma = MultipleAsker->new();

## Test of new()
# Much cleaner! (third argument is what to call the object)
isa_ok ($ma, 'MultipleAsker', 'ma');

## Test ofFive()
# Compare values as seperate arguments
is ($ma->ofFive(24), 0, '24 is not multiple of 5');
is ($ma->ofFive(25), 1, '25 is multiple of 5');

# Opposite of is, checks that first and second argument are not the same
isnt ($ma->ofFive(5), 0, '5 is multiple of 5');

## Test ofThirty()

# Show how to compare explicitly
cmp_ok ($ma->ofThirty(34), '==', 0, '34 is not multiple of 30');

# Finish the rest out, can still use ok()
ok ($ma->ofThirty(120) == 1, '120 is multiple of 30');
ok ($ma->ofThirty(30) == 1, '30 is multiple of 30');


Ask you can tell, there are several new methods available to use. Much more handy! Much cleaner and shorter way to test things that are not just an evaluation. While 'ok' works, it is not as clear as some of the names of the other methods... you can figure out what is being tested and in what way much easier with Test::More.

Oh! I almost forgot, here is the output:
1..8
ok 1 - use MultipleAsker;
ok 2 - ma isa MultipleAsker
ok 3 - 24 is not multiple of 5
ok 4 - 25 is multiple of 5
ok 5 - 5 is multiple of 5
ok 6 - 34 is not multiple of 30
ok 7 - 120 is multiple of 30
ok 8 - 30 is multiple of 30


As you can see, using these modules is very simple. Testing is meant to be very simple and test simple things only. While I'm not sure why anyone would want to use Test::Simple, it is available to you. Test::More is much more standard. All that really matters is that you do write tests.

Be sure to read the CPAN documentation for each module for a more complete description of all it's abilities.

Hope you increase your testing percentages if they aren't maxed out already!

No comments: