Five Test::More features you might not be using yet

I’ve been using Test::More for so long that I sometimes forget about new features that have been added in the last couple years. If you’re like me and would like a refresher, here’s a list of five useful features that you might want to start using. Unless otherwise noted, you will need at least version 0.88 of Test::More.

1. done_testing instead of no_plan

If you don’t know how many tests you are going to run (or don’t want to keep count yourself), you used to have to specify ‘no_plan’ at the start of your tests. That can lead to surprises if your tests exit prematurely. Instead, put the done_testing function at the end of your tests. This ensures that all tests actually run.

use strict; use warnings;
use Test::More 0.88;

ok(1, "first test");
ok(1, "second test");

done_testing;

2. new_ok for object creation

You used to have to create an object and then call isa_ok on it. Now those two can be combined with new_ok. It will also let you pass arguments in an arrayref to be used in the call to new.

use strict; use warnings;
use Test::More 0.88;

require Foo;
my $obj = new_ok("Foo");
# ... use $obj in testing ...

done_testing();

_Changed “requireok” to “require” per Ovid’s comment, below.

3. Add diagnostics only in verbose testing

The old diag function always prints to stderr. Particularly for debugging notes, that can clutter up the output when run under a harness. You can now use the note() function to add diagnostics that are only seen in verbose output.

use strict; use warnings;
use Test::More 0.88;

note("Testing on perl $]");
ok(1, "first test");

done_testing();

4. Explain data structures in diagnostics

I often find myself wanting to dump a data structure in diagnostics, and wind up loading Data::Dumper to do that. Now Test::More can do that for you with the explain() function. The output is a string that you can pass to diag or note.

use strict; use warnings;
use Test::More 0.88;

my $want = { pi => 3.14, e => 2.72, i => -1 };
my $have = get_data();

is_deeply($have, $want) or diag explain $have;

done_testing();
use strict; use warnings;
use Test::More 0.96;

pass("First test");

subtest 'An example subtest' => sub {
  pass("This is a subtest");
  pass("So is this");
};

pass("Third test");

done_testing();

Subtests can have their own plan, but if they don’t have one, Test::More acts like there was an implicit done_testing at the end of the code reference. That means you don’t have to keep count of tests in a subtest and things still work safely.

You can use a ‘skip_all’ plan in a subtest, too, which is a useful way of constructing a SKIP block without having to count how many tests are being skipped the way you would with the skip() function.

use strict; use warnings;
use Test::More 0.96;

pass("First test");

subtest 'Like a SKIP block' => sub {
  plan 'skip_all' unless $required_condition;
  pass("This is a subtest");
  # ... many more tests that you don't have to count ...
};

pass("Third test");

done_testing();