Testing in Perl
Learn the basics of Test::More - ok, is, and done_testing - and how to run your test suite with prove.
Introduction
A script you cannot verify automatically is a script you will eventually break without noticing. Perl has a mature, built-in testing culture centered on the core module Test::More, and a standard test runner called prove. This lesson writes a small module and a real test file for it.
- Why automated tests matter, even for small scripts.
- The core Test::More functions: ok, is, and like.
- How to declare a test plan or use done_testing instead.
- How to run a test suite with prove.
Why Test Perl Code
Tests let you change code with confidence - if you break something, a test fails immediately instead of the bug surfacing weeks later in production. They also work as living documentation: a well-named test describes exactly what a function is supposed to do.
Introducing Test::More
Test::More has shipped with Perl since version 5.6.2, so it is available essentially everywhere without installing anything extra. It provides a family of small, focused assertion functions, each of which prints a standardized "ok" or "not ok" line that testing tools can parse.
The ok Function
ok($condition, $description) is the simplest assertion: it passes if $condition is true, and fails otherwise. The description shows up in the test output, so make it specific enough to be useful on its own.
ok(1 == 1, 'one equals one');ok(defined $some_value, 'the value is defined');The is Function for Comparisons
is($got, $expected, $description) compares two values with eq semantics and, importantly, prints both the value you got and the value you expected when the test fails - far more useful for debugging than a plain ok(...) would be.
is(2 + 2, 4, '2 + 2 equals 4');is('perl' . '!', 'perl!', 'string concatenation works');Testing Errors with like
like($got, qr/pattern/, $description) checks that a value matches a regular expression - the standard way to test that die produced the error message you expected, without requiring an exact string match.
Declaring the Test Plan
Test::More can either be told up front exactly how many tests to expect (use Test::More tests => 4;) or, more commonly in modern code, you simply call done_testing() once at the very end of the file. Either approach lets the test harness detect if the script died partway through and ran fewer tests than intended.
A Complete Test File Example
Here is a small module and a matching test file that exercises it, using ok, is, and like together.
package Calculator;use strict;use warnings;
sub add { my ($a, $b) = @_; return $a + $b;}
sub divide { my ($a, $b) = @_; die "Cannot divide by zero\n" if $b == 0; return $a / $b;}
1;use strict;use warnings;use Test::More;use Calculator;
is(Calculator::add(2, 3), 5, 'add() sums two numbers');is(Calculator::add(-1, 1), 0, 'add() handles negatives');is(Calculator::divide(10, 2), 5, 'divide() computes correctly');
eval { Calculator::divide(10, 0) };like($@, qr/Cannot divide by zero/, 'divide() dies on zero');
done_testing();Running Tests with prove
prove is the standard command-line test harness that ships with Perl. Point it at one or more .t files (by convention kept in a t/ directory) and it runs them, summarizing pass/fail results.
prove -v t/calculator.tClick Run to see what this code prints.
Common Mistakes
- Forgetting done_testing() (or a matching tests => N plan), so prove cannot tell if the test file died early.
- Comparing floating-point numbers with is(), which can fail on tiny rounding differences - use a delta comparison instead.
- Not requiring the module under test correctly, causing every test to fail with an unrelated "Can't locate" error.
- Writing tests that depend on execution order or leftover state from a previous test.
- Giving every assertion the same vague description, making a failing test output useless.
Best Practices
- Give every assertion a specific, descriptive message - it is what you will read first when something fails.
- Keep test files under a t/ directory, following Perl's standard convention.
- Prefer done_testing() over a hardcoded plan when the number of tests may change over time.
- Use like() with qr/.../ to test error messages instead of exact string matches.
- Run the full test suite with prove -lv t/ regularly, and wire it into continuous integration.
Frequently Asked Questions
No - it has been part of core Perl since version 5.6.2, so it is available anywhere Perl itself is installed.
ok checks a single boolean condition, while is compares two values directly and prints both the expected and actual values on failure, which is much easier to debug.
It is a test harness: it runs one or more .t files, parses their standardized ok/not ok output, and prints a clear pass/fail summary for the whole run.
Key Takeaways
- Test::More ships with core Perl and provides ok, is, like, and more.
- is() gives better failure diagnostics than a plain ok() for equality checks.
- like() is the standard way to test that an error message matches a pattern.
- done_testing() (or an explicit plan) lets the test harness detect early failures.
- prove runs .t files and summarizes results, and is the standard way to run a Perl test suite.
Summary
Test::More and prove give Perl a lightweight, built-in testing workflow with no extra installation required. With testing covered, the next lesson turns to something every language has plenty of: the mistakes beginners make most often.