Optional tests for optional requirements
There are some modules on CPAN that provide optional features, where the availability of the feature is dependent on one or more other modules. One common example is optional support for export of data as an SQLite database, which is only supported if DBD::SQLite is installed.
Of course you want tests for all features of your module, and that means you need an optional test for your optional feature. And that's where Test::Requires comes in.
Let's say you've got some module that builds up information from the net, then can export it in a number of formats. There might be some core formats, like JSON and XML, but there might be some optional ones, such as SQLite. So in your test directory, you might have a file `export-as-sqlite.t`, which would start with:
If DBD::SQLite isn't available, then the entire test-suite will be skipped. Unless you're running release tests (for example when running `dzil release`), in which case the test-suite will bail out.
You can also use Test::Requires to require a particular version of Perl for a specific test-suite:
How do people use it in real life?
Sometimes you discover a new module that seems pretty groovy, but you can't imagine a use case where you might actually use it. A handy tip for such situations: use grep.cpan.me to find out how other people use the module. In the search box just enter:
BPM::Engine is a "Business Process Execution Engine", which can use various database back-ends. It has a class
t::TestUtils used by all of the tests, and in there you'll see the line:
There's an additional small point illustrated here. To run this test you also need DBI installed, but given that DBD::SQLite depends on DBI, you are essentially covering both with the above statement. In general, if there's a chain of dependencies, you only need to specify the last module in the chain.
namespace::autoclean is used to ensure that symbols imported into your module don't pollute your namespace. It has a test file moo.t, which tests usage of namespace::autoclean with Moo. At the start of this file you'll see the following, which means that Moo isn't required to install namespace::autoclean
Why this funny-looking construct? Unfortunately
use Test::Requires 'Foo::Bar' ends up running
eval "use Foo::Bar", which means that if
Foo::Bar exports any symbols by default, then they'll end up in your namespace. Putting this in a sacrificial namespace avoids that problem.
Toby Inkster's Kavorka provides function and method declaration keywords that support signatures. Typically for Toby, he's made sure it plays nicely with Moose, Mouse, and Moo. So in the test-suite 21modifiers-moose.t you'll see:
This shows the syntax for specifying a minimum required version of the module.
Above I said that you only need to use
Test::Requires on the last module in a dependency chain. But sometimes a test might require two independent modules. For example, ZeroMQ's 006_anyevent.t has the line:
Which means the test will be skipped unless both modules are installed.
Similarly other modules have optional tests using Devel::Monitor.
Test::Requires is handy when writing tests for a distribution that provides optional features based on modules in other CPAN distributions. Some common examples are:
Supporting multiple database engines.
Supporting multiple template engines.
Where some things are only accessible via https, so you need IO::Socket::SSL.
Supporting multiple formats like YAML, JSON, XML.
Running some tests only if certain
Devel::modules are installed.
One thing to be aware of:
Test::Requires ends up
use'ing the target modules.