Test::More - yet another framework for writing test scripts
| Use Case | Command | Description |
|---|---|---|
| ๐ข Plan tests | use Test::More tests => 23; | Declare a fixed number of tests |
| ๐ Declare plan at end | done_testing($n) | Plan when tests are done |
| โญ๏ธ Skip entire script | use Test::More skip_all => $reason; | Skip test script with reason |
| โ Basic pass/fail | ok($got eq $expected, $name) | Check if expression is true |
| ๐ String equality | is($got, $expected, $name) | Compare with eq |
| โ String inequality | isnt($got, $expected, $name) | Compare with ne |
| ๐ฌ Regex match | like($got, qr/pattern/, $name) | Check if string matches pattern |
| ๐ซ Regex non-match | unlike($got, qr/pattern/, $name) | Check if string does NOT match |
| โ๏ธ Custom comparison | cmp_ok($got, '==', $expected, $name) | Compare using any binary operator |
| ๐ฆ Module load | require_ok($module) | Check module can be loaded |
| ๐ฆ Use module | use_ok($module, @imports) | Check module can be used |
| ๐งฉ Deep structure comparison | is_deeply($got, $expected, $name) | Compare complex data structures |
| ๐ Method existence | can_ok($module, @methods) | Check if object can do methods |
| ๐ท๏ธ Class/type check | isa_ok($object, $class) | Check object isa class |
| ๐ Create and check | new_ok($class, \@args) | Create object and run isa_ok |
| ๐งช Subtest | subtest $name => sub { ... } | Run a nested test with its own plan |
| โญ๏ธ Skip tests | SKIP: { skip $why, $n; ... } | Conditionally skip a block of tests |
| ๐ TODO tests | TODO: { local $TODO = $why; ... } | Mark expected failures |
| ๐ Abort all tests | BAIL_OUT($reason) | Terminate testing immediately |
use Test::More tests => 23;
# or
use Test::More skip_all => $reason;
# or
use Test::More; # see done_testing()
require_ok( 'Some::Module' );
# Various ways to say "ok"
ok($got eq $expected, $test_name);
is ($got, $expected, $test_name);
isnt($got, $expected, $test_name);
# Rather than print STDERR "# here's what went wrong\n"
diag("here's what went wrong");
like ($got, qr/expected/, $test_name);
unlike($got, qr/expected/, $test_name);
cmp_ok($got, '==', $expected, $test_name);
is_deeply($got_complex_structure, $expected_complex_structure, $test_name);
SKIP: {
skip $why, $how_many unless $have_some_feature;
ok( foo(), $test_name );
is( foo(42), 23, $test_name );
};
TODO: {
local $TODO = $why;
ok( foo(), $test_name );
is( foo(42), 23, $test_name );
};
can_ok($module, @methods);
isa_ok($object, $class);
pass($test_name);
fail($test_name);
BAIL_OUT($why);
# UNIMPLEMENTED!!!
my @status = Test::More::status;
STOP! If you're just getting started writing tests, have a look at Test2::Suite first.
This is a drop in replacement for Test::Simple which you can switch to once you get the hang of basic testing.
The purpose of this module is to provide a wide range of testing utilities. Various ways to say "ok" with better diagnostics, facilities to skip tests, test future features and compare complicated data structures. While you can do almost anything with a simple "ok()" function, it doesn't provide good diagnostic output.
Before anything else, you need a testing plan. This basically declares how many tests your script is going to run to protect against premature failure.
The preferred way is to declare a plan when you "use Test::More":
use Test::More tests => 23;
If you don't know beforehand, declare at the end:
use Test::More;
... run your tests ...
done_testing( $number_of_tests_run );
NOTE: "done_testing()" should never be called in an "END { ... }" block.
Sometimes you want to skip an entire script:
use Test::More skip_all => $skip_reason;
To control exports, use the 'import' option:
use Test::More tests => 23, import => ['!fail'];
Alternatively, use plan():
use Test::More;
plan tests => keys %Stuff * 3;
Or for conditional skipping:
use Test::More;
if( $^O eq 'MacOS' ) {
plan skip_all => 'Test irrelevant on MacOS';
} else {
plan tests => 42;
}
done_testing
done_testing();
done_testing($number_of_tests);
If you don't know how many tests you're going to run, issue the plan when you're done. Safer than "no_plan".
By convention, each test is assigned a number. Assigning a name helps identify failures:
ok 4 - basic multi-variable
not ok 5 - simple exponential
ok 6 - force == mass * acceleration
All test functions take an optional name argument.
The basic purpose is to print "ok #" or "not ok #". All return true/false.
okok($got eq $expected, $test_name);
Evaluates expression; true passes, false fails. Produces diagnostics on failure.
ok( $exp{9} == 81, 'simple exponential' );
ok( Film->can('db_Main'), 'set_db()' );
ok( $p->tests == 4, 'saw tests' );
ok( !grep(!defined $_, @items), 'all items defined' );
is / isntis ( $got, $expected, $test_name );
isnt( $got, $expected, $test_name );
Compare with eq / ne. Better diagnostics than ok().
is( ultimate_answer(), 42, "Meaning of Life" );
isnt( $foo, '', "Got some foo" );
Do not use is() for boolean checks; use ok().
likelike( $got, qr/expected/, $test_name );
Matches against regex. Accepts qr// or string like '/expected/'.
like($got, qr/expected/, 'this is like that');
unlikeunlike( $got, qr/expected/, $test_name );
Checks that $got does NOT match the pattern.
cmp_okcmp_ok( $got, $op, $expected, $test_name );
Compare using any binary Perl operator. Useful for numeric comparisons.
cmp_ok( $got, 'eq', $expected, 'this eq that' );
cmp_ok( $got, '==', $expected, 'this == that' );
cmp_ok( $got, '&&', $expected, 'this && that' );
cmp_ok( $some_value, '<=', $upper_limit );
can_okcan_ok($module, @methods);
can_ok($object, @methods);
Checks if module/object can do the methods. Counts as one test regardless of number of methods.
can_ok('Foo', qw(this that whatever));
isa_okisa_ok($object, $class, $object_name);
isa_ok($subclass, $class, $object_name);
isa_ok($ref, $type, $ref_name);
Checks $object->isa($class) and that object is defined.
isa_ok( $obj, 'Some::Module' );
isa_ok( 'Vole', 'Rodent' );
isa_ok( $array_ref, 'ARRAY' );
new_okmy $obj = new_ok( $class );
my $obj = new_ok( $class => \@args );
my $obj = new_ok( $class => \@args, $object_name );
Creates object and calls isa_ok() on it.
subtestsubtest $name => \&code, @args;
Runs code as its own test with its own plan. Counts as one test for the parent.
use Test::More tests => 3;
pass("First test");
subtest 'An example subtest' => sub {
plan tests => 2;
pass("This is a subtest");
pass("So is this");
};
pass("Third test");
Returns true if subtest passed.
pass / failpass($test_name);
fail($test_name);
Synonyms for ok(1) and ok(0). Use very sparingly.
require_okrequire_ok($module);
require_ok($file);
Tries to require the module/file. Passes on success, fails with load error.
require_ok "Some::Module";
require_ok "Some/File.pl";
use_okBEGIN { use_ok($module); }
BEGIN { use_ok($module, @imports); }
Like require_ok but uses the module. Recommended inside BEGIN block.
BEGIN { use_ok('Some::Module', qw(foo bar)) }
BEGIN { use_ok('Some::Module', 1.02) }
is_deeplyis_deeply( $got, $expected, $test_name );
Deep comparison of references. Shows where they differ.
Note: has limitations with overloading; consider Test2::Suite for better alternatives.
diagdiag(@diagnostic_message);
Prints a diagnostic message that won't interfere with test output. Returns false.
ok( grep(/foo/, @users), "There's a foo user" ) or
diag("Since there's no foo, check that /etc/bar is set up right");
notenote(@diagnostic_message);
Like diag() but only visible in verbose TAP stream.
explainmy @dump = explain @diagnostic_message;
Dumps references in human-readable format.
is_deeply($have, $want) || diag explain $have;
SKIP: {
skip $why, $how_many if $condition;
...normal testing code goes here...
}
Declares a block of tests that may be skipped.
SKIP: {
eval { require HTML::Lint };
skip "HTML::Lint not installed", 2 if $@;
my $lint = new HTML::Lint;
isa_ok( $lint, "HTML::Lint" );
$lint->parse( $html );
is( $lint->errors, 0, "No errors found in HTML" );
}
TODO: {
local $TODO = $why if $condition;
...normal testing code goes here...
}
Declares tests that are expected to fail.
TODO: {
local $TODO = "URI::Geller not finished";
my $card = "Eight of clubs";
is( URI::Geller->your_card, $card, 'Is THIS your card?' );
my $spoon;
URI::Geller->bend_spoon;
is( $spoon, 'bent', "Spoon bending, that's original" );
}
TODO: {
todo_skip $why, $how_many if $condition;
...normal testing code...
}
For tests that cannot be run (cause die/hang). Marked as failing but todo.
Use SKIP for conditions the user cannot control (missing modules, OS features). Use TODO for programmer's unfinished work or bugs.
BAIL_OUTBAIL_OUT($reason);
Terminates all testing immediately. Exits with 255.
These functions produce no diagnostics; use is_deeply() instead.
eq_array(\@got, \@expected) โ deep array comparisoneq_hash(\%got, \%expected) โ deep hash comparisoneq_set(\@got, \@expected) โ set comparison (order irrelevant, but duplicates matter)buildermy $test_builder = Test::More->builder;
Returns the underlying Test::Builder object.
If all tests passed, exit with 0. If anything failed, exit with number of failures. If less/more tests than planned, considered failures. If no tests run, exit 255. If test died, exit 255.
0 all tests successful
255 test died or all passed but wrong # of tests run
any other number how many failed (including missing or extras)
If more than 254 failures, reported as 254.
Test::More works with Perl 5.8.1+.
Use use open ':std', ':encoding(utf8)'; before loading Test::More, or set encodings on Test::Builder filehandles.
Handled as strings; is_deeply cannot test internals of string overloaded objects.
Require use threads before use Test::More. Supports 5.8.1+.
Convergent evolution with Joshua Pritikin's Test module. Goal: simple, quick, flexible testing utility.
Michael G Schwern <schwern AT pobox.com> with inspiration from Joshua Pritikin and help from many.
Chad Granum <exodist AT cpan.org>
See https://github.com/Test-More/test-more/issues
http://github.com/Test-More/test-more/
Copyright 2001-2008 by Michael G Schwern. This program is free software; you can redistribute it under the same terms as Perl itself.
Generated by phpman v4.9.26-1-g511901d · Markdown · JSON · MCP Author: Che Dong Under GNU General Public License
2026-07-31 02:46 @216.73.217.152
CrawledBy Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
Enhanced by LLM: deepseek-v4-flash / taotoken.net / www.chedong.com - original format