Perl: Basic Unit Testing
February 9, 2008 | by Adam Pope
Good software engineering practice dictates that we should always write tests for all of our modules and classes. These tests are called Unit Tests and allow us to perform regression tests every time we change a unit – so we can ensure we haven’t broken anything in the process. The problem is, it can be very time consuming and often regarded as ‘boring’ to write these tests. Thankfully, CPAN provides a number of modules to make this very easy in Perl.
In this tutorial, we go through the process of creating the simplest of test scrips and some easy extensions to make your tests more powerful.
We are going to use the Test::Simple CPAN module to build our test script, so include the module at the top of a new Perl file:
use Test::Simple tests => 2;
The basic building block of our tests will be the ok() function. This takes two arguments, an expression in scalar context and the test name (this can be omitted, but it makes debugging easier as your test script grows) and will indicate whether the test passed or failed in the output to STDOUT.
ok ( $value eq $expected, "Test Name" ); ok ( $value < $expected );
The expression will be evaluated when the test is run. The test will pass if the result evaluates to true or fail otherwise. You can use this, along with the fact we are working in scalar context, to perform some more interesting tests. For example, this test will succeed if the array is non-empty:
ok( @my_array, "Array not empty" );
Already we have seen enough to build a reasonably powerful test suite and help us build better software. However, there are some situations where we need a little more flexibility and for these we have Test::More. Test::More is a drop-in replacement for Test::Simple – you can simply change your module include and it will work exactly as before.
use Test::More tests => 2;
Test::More gives us a range of new functions to perform more complex and powerful tests with better diagnostics. First up we have is() and isnt():
is( $value, $expected, "Test name" ); isnt( $value, $expected, "Test name" );
These compare the first two arguments with eq and ne respectively. Test::More also has native support for regular expression with 2 complementary functions: like() and unlike().
like( $value, qr/expected/, "Test name" ); unlike( $value, qr/expected/, "Test name" );
Finally, we have the cmp_ok() function. This is operates in between the flexibility of ok() and the rigidity of is() by allowing you to specify the two operands and the operator:
cmp_ok( $value, '==', $expected, "Test Name" ); cmp_ok( $value, '&&', $expected, "Test Name" );
This tutorial has only scratched the surface of the big world of unit testing but the key thing to remember is that doing ANY unit testing is better than doing none, so go ahead and create some simple, repeatable tests and improve the quality of your programs.