My Favourite Test::* Modules

This is a very old article. It has been imported from older blogging software, and the formatting, images, etc may have been lost. Some links may be broken. Some of the information may no longer be correct. Opinions expressed in this article may no longer be held.

If you don’t test your code, what makes you think it works?!

Here are some of my favourite modules for testing Perl code.

General Purpose Testing

Test::More is the foundation of all my test scripts. Indeed, the majority of the test scripts use nothing beyond it. It provides the is() function useful for testing code that produces string and numeric output; like() is also very useful for testing strings; and is_deeply() is great for testing most nested data structures.

For many of my test suites, I rely on at least version 0.96 of Test::More. This was the first stable version after some important improvements to subtests, and it’s nice to be able to rely on a good implementation of subtests. Every version of Perl since 5.13.4 has been bundled with a sufficiently recent Test::More, and it’s usually a pretty simple upgrade on older Perls.

It’s important to test your code behaves as documented under normal conditions, but it is equally important to test that it behaves as documented under abnormal circumstances, such as when it is passed bad input data. For this purpose, I strongly recommend Test::Fatal and Test::Warnings. There are various other modules that do similar jobs, but these are two that seem to get the balance between features and complexity about right.

Sometimes you’ve written code that can interact with other modules. But your code doesn’t rely on those modules, so you don’t want to list it as a dependency. So you want to skip the tests for these features if those modules are not installed. This is easy enough to do by calling Test::More’s plan skip_all => $reason, but easier still using Test::Requires.

Another useful testing module is Test::Deep. Test::Deep takes is_deeply() a step further, allowing you more flexibility in declaring whether two structures are equivalent. Perhaps you don’t care whether a particular value in a hash exactly matches a certain string, but do care that it matches a certain regexp. Or perhaps some array deeply nested in your data structure should be treated as a set (i.e. you care what items are in it, but not what order they appear in). Test::Deep can handle all of that and more.

Finally for general purpose testing, I’ll mention Test::LongString which provides equivalents of Test::More’s is() and like() functions, but with more useful diagnostics, helping you track down the bytes where long strings differ.

Special Purpose Testing

Depending on what you’re doing, there are various special-purpose testing modules that might make your life easier.

Test::Moose is useful for testing Moose classes, and its with_immutable function is very useful for testing MooseX::* modules too.

Test::RDF is good for testing RDF graphs, such as data from FOAF files, RSS 1.0 feeds, and the Facebook Open Graph Protocol.

Test::HTTP::Server is not really a testing module, but a light-weight HTTP server, suitable for testing HTTP clients. It unfortunately doesn’t support Windows machines, so you may need to skip tests based on $^O.

Test::TypeTiny is useful for testing type constraint libraries. It is bundled with Type::Tiny, but can also be used to test MooseX::Types and MouseX::Types constraints.

Finally, if you’ve written your own test module, Test::Tester is a great way to test it.

Quality Assurance

There are a lot of modules on CPAN which aren’t so much concerned with testing that your code works, but instead test other aspects of the software development process. For example, they can test that your work complies with particular source code formatting policies, or is properly documented. I won’t go into these in detail, but I routinely use Test::Pod, Test::Pod::Coverage, Test::Spellunker, Test::Tabs, Test::EOL, and Test::HasVersion.