Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Design

Perl Testing


For Further Exploration

Once you've mastered the basics of Perl testing, you may be interested in more advanced capabilities. For rigorous unit testing of legacy object-oriented applications, Test::MockObject provides a complete, if lengthy, solution. Test::MockObject lets you create objects that mock the behavior of the ones actually used in your application so they present apparently the same interface to the calling tests but under your complete control and without the side effects. (Testing a database is such a common need for mocking that the module DBD::Mock was created to help with it.) This is so-called "white box" testing: instead of looking only at the interfaces a method presents to the outside world, you craft unit tests for it by inspecting its code to see where it calls functions or methods that may alter state. Then you mock those functions to track whether they are being called the way you expect at that point.

If you like to integrate code and its documentation, you might like to do the same with its tests, in which case the CPAN module Test::Inline lets you embed tests within code in an extension of the POD language. Just encapsulate them in POD-like blocks marked "=begin testing" ... "=end testing" and then extract the tests into a test file with the program pod2test that comes with Test::Inline. (This step can be automated in your module's Makefile.PL during the make test phase.)

Test::Unit

If you're coming from a Java/JUnit background and want a familiar testing environment in Perl, the CPAN module Test::Unit is for you. You define set_up() and tear_down() procedures to prepare for and clean up after each test case so there can be no side effects between tests. Test::Unit even provides the green/red bar, courtesy of PerlTk.

Coverage Testing

The value of tests is proportional to the proportion of possible equivalence classes that are exercised. Generating the valid equivalence classes is still a manual task, but you can at least verify that all the statements in your code have been exercised during testing. Once again, this has been automated. Modules for measuring code coverage have existed for some time: Devel::DProf and Devel::SmallProf profile code and the parts that haven't been called can be inferred. Devel::Coverage shows them explicitly. But that's still too much work for the lazy. Therefore the modern module Devel::Cover has been extended to include coverage for tests. Now, simply by defining an environment variable, you can trigger analysis during make test and generate a coverage database that can be analyzed with the cover program that comes with Devel::Cover. That program outputs HTML that provides a tabular representation of the lines of code that did not get exercised. There's even another module, Test::Pod::Coverage, that verifies that all the files in your distribution provide documentation.

Legacy Application Testing

Perl programmers are often faced with having to deal with legacy applications which lack unit tests or, for that matter, coherent units. Perl's testing framework at this point becomes useful for creating end-to-end regression tests to provide a safety net while the application is modified. This can even be extended to testing web interfaces via the CPAN module Test::WWW::Mechanize. If you find the work of programming the necessary inputs to navigate a web interface too tedious, the module HTTP::Recorder will do it for you.

Automated tests can be useful for other purposes than just application testing. With the web-based testing tools just mentioned, you could write something like Listing Four to verify that your bank account is doing alright. (If you want to put it in a cron job, knowing that the exit code of a test run is the number of tests that failed may be useful.)

use strict;
use warnings;

use Test::WWW::Mechanize tests => 7;

my $mech = Test::WWW::Mechanize->new;

$mech->get_ok("http://www.mybank.example.com/", "My bank is still there");
$mech->content_contains("Login", "and it still has a login page");

my ($username, $password) = @ARGV;
$mech->set_visible($username, $password);

ok($mech->submit->is_success, "Login form submitted okay");
$mech->content_like(qr/Account data/, "Logged in okay");

my ($balance) = $mech->content =~ /Checking: \$([\d.]+)/;
ok(defined($balance), "Found checking account balance");

ok($balance > 1000, "Got enough for now");

Listing Four


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.