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();