LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 3316 min read

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.

What You Will Learn
  • 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.

Calculator.pm
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;
t/calculator.t
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.t
Output

Click Run to see what this code prints.

Common Mistakes

Avoid These 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.

Next Lesson →

Common Beginner Mistakes