testing intermediate

How to use subtest for grouped tests in Perl?

Question

How to use subtest for grouped tests in Perl?

The subtest function from Test::More allows grouping related tests under a named block, improving test output clarity. However, when using subtest, it's important to correctly count the total number of tests your entire script runs — including all tests inside all subtests combined.

The common pitfall in your example is the mismatch between the declared plan (tests => 7) and the actual number of tests. Your three subtests contain 3, 2, and 2 tests respectively, totaling 7 tests inside subtests—but because subtest only counts outer tests by default (one per subtest), your script wrongly counts 3 tests.

To fix this, remove the explicit plan and instead call done_testing at the end of your script. This lets Test::More automatically count tests run—both inside and outside subtests—solving the mismatch problem.

How to use subtest properly with automatic test counting

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

subtest 'string tests' => sub {
    ok('Hello' eq 'Hello', 'Strings are equal');
    is(length('Hello'), 5, 'Length of string is 5');
    like('World', qr/orld/, 'World contains "orld"');
};

subtest 'array tests' => sub {
    my @arr = (1, 2, 3);
    is(scalar @arr, 3, 'Array length is 3');
    is($arr[0], 1, 'First element is 1');
};

subtest 'hash tests' => sub {
    my %hash = ( apple => 'red', banana => 'yellow' );
    ok(exists $hash{'apple'}, 'Key apple exists');
    is($hash{'banana'}, 'yellow', 'Banana is yellow');
};

done_testing();

This script will output:

ok 1 - string tests
    ok 1 - Strings are equal
    ok 2 - Length of string is 5
    ok 3 - World contains "orld"
ok 2 - array tests
    ok 1 - Array length is 3
    ok 2 - First element is 1
ok 3 - hash tests
    ok 1 - Key apple exists
    ok 2 - Banana is yellow
1..8

Key Details

  • subtest groups tests and reports them indented under a named label.
  • When specifying tests => N manually, you must count all assertions inside subtests precisely.
  • Omitting the plan and calling done_testing is safer and more flexible, especially with nested tests.
  • The test number at the end (1..8) counts each subtest as one test plus all contained assertions.
  • Remember to use use Test::More; and not just subtest, which depends on it.

Summary

  • Use subtest to logically group related tests for clarity.
  • Prefer done_testing() to avoid mismatches in test count plans.
  • Always include use Test::More; to access subtest and other testing functions.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 59ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
# Subtest: string tests
    ok 1 - Strings are equal
    ok 2 - Length of string is 5
    ok 3 - World contains "orld"
    1..3
ok 1 - string tests
# Subtest: array tests
    ok 1 - Array length is 3
    ok 2 - First element is 1
    1..2
ok 2 - array tests
# Subtest: hash tests
    ok 1 - Key apple exists
    ok 2 - Banana is yellow
    1..2
ok 3 - hash tests
1..3
STDERR
(empty)

Was this helpful?

Related Questions