Testing with Test::More
🧪 Testing with Test::More
Test::More produces, originated in Perl and was later adopted as a language-agnostic standard used by testing tools well beyond Perl itself. This chapter covers writing and running real tests.
✅ The Basic Assertions
is() is preferred over ok($got == $expected, ...) for equality checks specifically because a failure reports both the actual and expected values automatically — genuinely more useful for diagnosing what went wrong than a bare pass/fail from ok alone.
📝 A First Test File
Test files conventionally live in a t/ directory and end in .t. done_testing(); at the end is the modern convention, replacing the older style of declaring use Test::More tests => 5; and having to keep that count manually in sync with the actual number of assertions.
▶️ Running Tests with prove
prove (installed alongside Perl itself) is the standard test runner — it executes every matched .t file and reports a clean pass/fail summary.
🏗️ Testing Data Structures
is($got, $expected, ...) on two references — even two hashrefs holding identical data — compares whether they're the exact same reference in memory (Course 1, Chapter 9's reference-vs-value distinction), not whether their contents match. Two separately-built hashrefs with identical keys and values will fail a plain is() check. is_deeply() is the correct tool for comparing the actual contents of nested arrays/hashes, recursively.
🔧 A Worked Example — Testing a Real Subroutine
This exercises a closure (Chapter 7) directly through Test::More's assertions — is() for the expected numeric results, like() confirming the output's shape via regex rather than an exact string match.
TAP: Perl's Testing Format, Adopted Widely
TAP (Test Anything Protocol) — the simple, line-based pass/fail output Test::More produces — originated in Perl's testing culture and was later formalized as a language-agnostic standard, with TAP producers and consumers built for many other languages beyond Perl. This is a genuine parallel to CPAN's own historical head start (Chapter 5): Perl's testing tooling matured early enough to influence testing practices well outside the language itself, much like PCRE's regex engine did.
ok / is / isnt / like
The core assertions — is() for equality reports both values on failure.
done_testing()
Modern style — no upfront test-count plan to keep in sync.
prove
The standard test runner — prove -r t/ runs every test file.
is_deeply
Compares reference contents recursively — is() alone only checks identity.
💻 Coding Challenges
Challenge 1: A Basic Test File
Write a test file t/strings.t with at least 3 assertions covering string concatenation, a regex match with like, and one intentionally-failing assertion (to see what a failure looks like) — then remove the failing one and confirm all tests pass with prove.
Challenge 2: Test a Subroutine From Course 1
Write a test file testing Course 1, Chapter 7's power subroutine (base and optional exponent, defaulting to 2) with at least 3 is() assertions covering both the default and an explicit exponent.
Challenge 3: is vs is_deeply
Given two separately-built arrayrefs both containing (1, 2, 3), write one assertion using is() (predict and note that it fails) and one using is_deeply() (predict and note that it passes), and explain in one sentence why they disagree.
🎯 What's Next
Final chapter: Perl One-Liners & Practical Text Processing — perl -e/-pe/-ne, closing the loop back to the Bash/sed/awk cluster.