NAME
Test::Most::Explain - Enhanced diagnostics for Test::More with structured diffs and helpful hints
VERSION
Version 0.01
SYNOPSIS
use Test::More;
use Test::Most::Explain qw(explain);
# Use explain() directly
my $msg = explain("foo", "fob");
diag $msg;
# Or rely on automatic diagnostic enhancement
is_deeply(
{ a => 1, b => [1,2,3] },
{ a => 1, b => [1,9,3] },
'deep structure mismatch'
);
# On failure, Test::Most::Explain replaces Test::More's
# default "got/expected" output with a structured diff
# and helpful hints.
DESCRIPTION
Test::Most::Explain provides clearer, more actionable diagnostics for failing tests. It works in two complementary ways:
Automatic enhancement of Test::More diagnostics
When the module is loaded, it installs a small wrapper around Test::Builder::diag. This wrapper detects Test::More's standard failure diagnostics:
Failed test ...
# got: ...
# expected: ...
Whenever such output is seen, Test::Most::Explain suppresses the original diagnostics and replaces them with a structured explanation generated by explain().
This means existing test code such as:
is_deeply($got, $exp, 'something');
automatically produces richer diagnostics like:
Deep structure comparison failed:
Got: { ... }
Expected: { ... }
Possible causes:
. Missing key in got: foo
. Array length differs
Only Test::More-style failure messages are intercepted. All other diag() calls pass through unchanged.
Motivation
Perl's default test diagnostics are functional but terse. When complex structures differ, the default output often shows only memory addresses. Test::Most::Explain aims to provide clearer diffs, contextual hints, and more helpful deep-structure reporting without adding heavy dependencies or requiring changes to existing test code.
METHODS
explain
Purpose: Produce a human-readable explanation of differences between two values. Handles scalars, arrays, hashes, blessed references, and mixed structures.
Arguments: ($got, $exp) - any two Perl values (scalars or references).
Returns: A string describing the difference. Never dies.
Side effects: None. This routine does not emit diagnostics; it only returns a string.
Notes: - Undef is normalized to an empty string for scalar comparison. - Deep structures are dumped using Data::Dumper.
Example:
my $msg = explain("foo", "fob");
diag $msg;
The explain() routine compares two values and returns a human-readable description of how they differ. It handles:
simple scalars
arrays
hashes
blessed references
mixed or unexpected structures
For scalars, explain() reports the first differing character and shows context around the mismatch. For deep structures, it emits compact dumps of each side and highlights structural issues such as:
differing array lengths
missing or extra hash keys
blessed vs unblessed mismatches
Unicode differences
leading or trailing whitespace
case-only differences
explain() never dies and always returns a string.
API Specification
Input (Params::Validate::Strict compatible)
{
got => { type => SCALAR | ARRAYREF | HASHREF | OBJECT, optional => 1 },
exp => { type => SCALAR | ARRAYREF | HASHREF | OBJECT, optional => 1 },
}
Output (Return::Set compatible)
{
result => STRING, # explanation text
}
AUTHOR
Nigel Horne, <njh at nigelhorne.com>
BUGS
SEE ALSO
REPOSITORY
https://github.com/nigelhorne/Test-Most-Explain
SUPPORT
This module is provided as-is without any warranty.
Please report any bugs or feature requests to bug-test-most-explain at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Most-Explain. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
You can find documentation for this module with the perldoc command.
perldoc Test::Most::Explain
You can also look for information at:
MetaCPAN
RT: CPAN's request tracker
CPAN Testers' Matrix
CPAN Testers Dependencies
LICENCE AND COPYRIGHT
Copyright 2026 Nigel Horne.
Usage is subject to licence terms.
The licence terms of this software are as follows:
Personal single user, single computer use: GPL2
All other users (including Commercial, Charity, Educational, Government) must apply in writing for a licence for use from Nigel Horne at the above e-mail.