Synopsis 24: Testing
Created: 30 Dec 2010
Last Modified: 14 August 2014
Version: 8
use Test;
plan 6; # not needed when using "done"
ok True, 'True is a true value';
nok False, 'False is a false value';
is 'ab'.uc, 'AB', 'successful string comparison';
diag "we may have some mathematical issues"
if !is-approx 2.sqrt, 1.4142135623, 'Approximate numeric comparison';
dies-ok { die "yes"}, 'exceptions';
dies-ok '1 1', 'two terms in a row are a parse error';
done; # not needed when doing "plan"
Perl 6 comes with a standard testing module, Test
. It is the testing module used by the official spectest suite.
The testing functions emit output conforming to the Test Anything Protocol. See http://testanything.org.
For the purposes of this document, a test file is a file that does use Test
.
All of the following functions are exported by default:
# planning number of tests
plan($number-of-tests)
done()
# unconditional passing/failing/notification
pass($desc?)
flunk($desc?)
diag($desc)
# skipping
todo($reason, $count = 1)
skip($reason, $count = 1)
skip-rest($reason?)
# evaluates $cond in boolean context
ok(Mu $cond, $desc?)
nok(Mu $cond, $desc?)
# comparisons
is(Mu $got, Mu $expected, $desc?)
isnt(Mu $got, Mu $expected, $desc?)
cmp-ok(Mu $got, $op, Mu $expected, $desc?)
# structural comparison with infix:<eqv>
is-deeply(Mu $got, Mu $expected, $desc?)
# numeric comparison with 1e-5
is-approx(Mu $got, Mu $expected, $desc?)
# class membership testing
isa-ok(Mu $var, Mu $type, $desc?)
# grouping of tests, ok only if all ok
subtest(&subtests, $desc?)
# exception testing
dies-ok($code, $desc?)
lives-ok($code, $desc?)
throws-like($code, $exception-type, $desc?, *%matcher)
sub plan($number-of-tests) is export { ... };
sub done() is export { ... };
In order to determine whether a test file ran all its tests, a plan()
function call can be made somewhere in the test file, providing a count of the total number of tests. A TAP harness can then flag an error condition when the number of tests actually run doesn't match.
If plan()
isn't called, done()
can be called at the end of the test file to output an automatically computed tally.
A TAP harness will consider it an error if neither plan()
nor done()
was called, or if there was more than one call in the test file, or if the call occurred between calling two test functions (rather than at the beginning or at the end).
All test functions take an optional description argument, which will be printed along with the ok
or not ok
result and the test number. Note that what is displayed as optional parameters in the list below might as well be implemented by some other mechanism, such as several multi sub
s. Such details are left as implementation-dependent.
The names of positional parameters are non-normative, so supplying the positional arguments to these test files by name is discouraged.
sub pass($desc?) is export { ... }
sub flunk($desc?) is export { ... }
The pass()
function marks a test as passed. The flunk()
function marks a test as not passed.
sub diag($message) is export { ... }
The diag()
function allows specific diagnostic information to be printed in a TAP-compatible manner on $*ERR
. It is usually used when a particular test has failed to provide information that the test itself did not provide. Or it can be used to provide visual markers on how the testing of a test-file is progressing (which can be important when doing stress testing).
sub todo($reason, $count = 1) is export { ... }
sub skip($reason, $count = 1) is export { ... }
sub skip-rest($reason?) is export { ... }
The todo()
function can be called before running other test functions, and marks the next $count
tests as TODO.
The skip()
function is called instead of the some tests (usually because they would die), and emits $count
SKIP markers in the TAP output.
The skip-rest()
function can be called conditionally to skip($remaining)
all of the remaining tests.
The todo()
and skip()
functions are generally automatically generated by some sort of source code fudging program.
sub ok(Mu $cond, $desc?) is export { ... }
sub nok(Mu $cond, $desc?) is export { ... }
The ok()
function marks a test as passed if the given condition evaluates to True
. The nok()
function marks a test as passed if the given condition evaluates to False
.
sub is(Mu $got, Mu $expected, $desc?) is export { ... }
sub isnt(Mu $got, Mu $expected, $desc?) is export { ... }
sub cmp-ok(Mu $got, $op, Mu $expected, $desc?) is export { ... }
The is()
function marks a test as passed if the obtained and expected values are the same. If $expected
is a type object, then $got
is compared using ===
. If $expected
is a defined value, then $got
is compared using eq
. The isnt()
function marks a test as passed if the obtained and expected values are not the same (using the same logic as with is()
).
The cmp-ok()
function compares two values with the given operator and passes the test if the comparison yields a True
value. For ease of use, operators may be passed as strings, such as '=='
or '~~'
. Note that you can also pass a custom operator, for special types of comparisons.
These functions are typically used to check scalar values.
sub is-deeply(Mu $got, Mu $expected, $desc?) is export { ... }
The is-deeply()
function marks a test as passed if the obtained and expected values are eqv
. This is the best way to check for equality of (deep) data structures.
sub is-approx(Mu $got, Mu $expected, $desc?) is export { ... }
The is-approx()
function marks a test as passed if the obtained and expected numerical values are within 1e-5
of each other.
sub isa-ok(Mu $object, Mu $type, $desc?) is export { ... }
The isa-ok()
function marks a test as passed if the given object is, or inherits from the given type. For convenience, types may also be specified as a string.
sub subtest(&subtests, $desc?) is export { ... }
The subtest()
function executes the given block, consisting of usually more than one test, possibly including a plan()
or done()
. It will pass the test only if all tests in the block, pass.
sub dies-ok(Callable $code, $desc?) is export { ... }
sub lives-ok(Callable $code, $desc?) is export { ... }
sub throws-like($code, $exception-type, $desc?, *%matcher) is export { ... }
The dies-ok()
passes the test if the given code throws an exception. The lives-ok()
passes the test if the given code does not throw an exception.
The throws-like()
function checks whether the given code (specified as either something Callable
, or as a something to be EVAL
led) throws a specific exception (either specified as a Type object, or as a string). If an exception was thrown, it will also try to match the matcher hash, in which the key is the name of the method to be called on the exception, and the value is the value it should have to pass.
Please note that you can only use the EVAL
form if you are not referencing any symbols in the surrounding scope. If you are, you should encapsulate your string with a block and an EVAL. For instance:
throws-like { EVAL q[ fac("foo") ] }, X::TypeCheck::Argument;
Moritz Lenz <moritz@faui2k3.org>
Carl Mäsak <cmasak@gmail.com>
Elizabeth Mattijsen <liz@wenzperl.nl>