NAME¶
Test::SimpleUnit - Simplified Perl unit-testing framework
SYNOPSIS¶
use Test::SimpleUnit qw{:functions};
runTests(
{name => "test1", test => sub {...}},
{name => "testN", test => sub {...}}
);
EXAMPLE¶
use Test::SimpleUnit qw{:functions};
# If a setup or teardown function fails, skip the rest of the tests
Test::SimpleUnit::AutoskipFailedSetup( 1 );
Test::SimpleUnit::AutoskipFailedTeardown( 1 );
my $Instance;
my $RequireWasOkay = 0;
my @tests = (
# Require the module
{
name => 'require',
test => sub {
# Make sure we can load the module to be tested.
assertNoException { require MyClass };
# Try to import some functions, generating a custom error message if it
# fails.
assertNoException { MyClass->import(':myfuncs') } "Failed to import :myfuncs";
# Make sure calling 'import()' actually imported the functions
assertRef 'CODE', *::myfunc{CODE};
assertRef 'CODE', *::myotherfunc{CODE};
# Set the flag to let the setup function know the module loaded okay
$RequireWasOkay = 1;
},
},
# Setup function (this will be run before any tests which follow)
{
name => 'setup',
test => sub {
# If the previous test didn't finish, it's untestable, so just skip the
# rest of the tests
skipAll "Module failed to load" unless $RequireWasOkay;
$Instance = new MyClass;
},
},
# Teardown function (this will be run after any tests which follow)
{
name => 'teardown',
test => sub {
undef $Instance;
},
},
# Test the connect() and disconnect() methods
{
name => 'connect() and disconnect()',
test => sub {
my $rval;
assertNoException { $rval = $Instance->connect };
assert $rval, "Connect failed without error.";
assertNoException { $Instance->disconnect };
},
},
# One-time setup function -- overrides the previous setup, but is
# immediately discarded after executing once.
{
name => 'setup',
func => sub {
MyClass::prepNetwork();
},
},
# Now override the previous setup function with a new one that does
# a connect() before each remaining test.
{
name => 'setup',
test => sub {
$Instance = new MyClass;
$Instance->connect;
},
}
# Same thing for teardown/disconnect()
{
name => 'teardown',
test => sub {
$Instance->disconnect;
undef $Instance;
},
},
...
);
runTests( @testSuite );
DESCRIPTION¶
This is a simplified Perl unit-testing framework for creating unit tests to be
run either standalone or under Test::Harness.
Testing¶
Testing in Test::SimpleUnit is done by running a test suite, either via 'make
test', which uses the Test::Harness 'test' target written by
ExtUtils::MakeMaker, or as a standalone script.
If errors occur while running tests via the 'make test' method, you can get more
verbose output about the test run by adding "TEST_VERBOSE=1" to the
end of the "make" invocation:
$ make test TEST_VERBOSE=1
If you want to display only the messages caused by failing assertions, you can
add a "VERBOSE=1" to the end of the "make" invocation
instead:
$ make test VERBOSE=1
Test Suites¶
A test suite is one or more test cases, each of which tests a specific unit of
functionality.
Test Cases¶
A test case is a unit of testing which consists of one or more tests, combined
with setup and teardown functions that make the necessary preparations for
testing.
You may wish to split test cases up into separate files under a "t/"
directory so they will run under a Test::Harness-style "make test".
Tests¶
A test is a hashref which contains two key-value pairs: a
name key with
the name of the test as the value, and a code reference under a
test
key:
{
name => 'This is the name of the test',
test => sub { ...testing code... }
}
Each test's "test" function can make one or more assertions by using
the Assertion Functions provided, or can indicate that it or any trailing
tests in the same test case should be skipped by calling one of the provided
Skip Functions.
Setup and Teardown Functions¶
If a test has the name 'setup' or 'teardown', it is run before or after each
test that follows it, respectively. A second or succeeding setup or teardown
function will supersede any function of the same type which preceded it. This
allows a test designer to change the setup function as the tests progress. See
the EXAMPLE section for an example of how to use this.
If a test is preceded by multiple new setup/teardown functions, the last one to
be specified is kept, and any others are discarded after being executed once.
This allows one to specify one-time setup and/or teardown functions at a given
point of testing.
The code reference value within a
setup or
teardown test case can
optionally be named "func" instead of "test" for clarity.
If there are both "func" and "test" key-value pairs in a
setup or
teardown case, the "test" pair is silently
ignored.
Saving Test Data¶
If the test suite requires configuration, or some other data which should
persist between test cases, it can be dumped via Data::Dumper to a file with
the
saveTestData() function. In succeeding tests, it can be reloaded
using the
loadTestData() function.
REQUIRES¶
Carp, Data::Compare, Data::Dumper, Exporter, Fcntl, IO::File, IO::Handle,
Scalar::Util
EXPORTS¶
Nothing by default.
This module exports several useful assertion functions for the following tags:
- :asserts
- assert, assertNot, assertDefined, assertUndef,
assertNoException, assertException, assertExceptionType,
assertExceptionMatches, assertEquals, assertMatches, assertRef,
assertNotRef, assertInstanceOf, assertKindOf, fail
- :skips
- skipOne, skipAll
- :testFunctions
- runTests
- :testdata
- loadTestData, saveTestData
- :functions
- All of the above.
AUTHOR¶
Michael Granger <ged@FaerieMUD.org>
Copyright (c) 1999-2003 The FaerieMUD Consortium. All rights reserved.
This module is free software. You may use, modify, and/or redistribute this
software under the terms of the Perl Artistic License. (See
http://language.perl.com/misc/Artistic.html)
FUNCTIONS¶
- AutoskipFailedDataLoad( $trueOrFalse
)
- If set to a true value, any failure to reload test data via
loadTestData() will cause the test to be skipped instead of
running.
- AutoskipFailedSetup( $trueOrFalse
)
- If set to a true value, any failed setup functions will
cause the test to be skipped instead of running.
- AutoskipFailedTeardown( $trueOrFalse
)
- If set to a true value, any failed teardown functions will
cause the test to be skipped instead of running.
- Debug( $trueOrFalse )
- If set to a true value, the test suite will be dumped to
STDERR before running.
- OutputHandle( $handle )
- Set the handle that will be used to output test
progress information. This can be used to run tests under Test::Harness
without influencing the test result, such as when invoking
runTests() from within an assertion. It defaults to STDOUT, which
will be what it is restored to if it is called with no argument. The
argument is tested for support for the 'print', 'flush', and 'printf'
methods, and dies if it does not support them. This function is mostly to
support self-testing.
- runTests( @testSuite )
- Run the tests in the specified testSuite, generating output
appropriate for the harness under which it is running. The testSuite
should consist of one or more hashrefs of the following form:
Assertion Functions¶
- assert( $value[,
$failureMessage ] )
- Die with a failure message if the specified value is not
true. If the optional failureMessage is not given, one will be
generated.
- assertDefined( $value[,
$failureMessage ] )
- Die with a failure message if the specified value is
undefined. If the optional failureMessage is not given, one will be
generated.
- assertEquals( $wanted,
$tested[, $failureMessage] )
- Die with a failure message if the specified wanted value
doesn't equal the specified tested value. The comparison is done with
Data::Compare, so arbitrarily complex data structures may be compared, as
long as they contain no GLOB, CODE, or REF references. If the optional
failureMessage is not given, one will be generated.
- assertException( \&code[,
$failureMessage] )
- Evaluate the specified coderef, and die with a
failure message if it does not generate an exception. If the optional
failureMessage is not given, one will be generated.
- assertExceptionMatches( \&code,
$regex[, $failureMessage] )
- Evaluate the specified coderef, and die with a
failure message if it does not generate an exception which matches the
specified regex. If the optional failureMessage is not
given, one will be generated.
- assertExceptionType( \&code, $type[,
$failureMessage] )
- Evaluate the specified coderef, and die with a
failure message if it does not generate an exception which is an object
blessed into the specified type or one of its subclasses (ie., the
exception must return true to "$exception-"isa($type)>. If
the optional failureMessage is not given, one will be
generated.
- assertInstanceOf( $wantedClass,
$testedValue [, $failureMessage] )
- Die with a failure message if the specified testedValue is
not an instance of the specified wantedClass. If the optional
failureMessage is not given, one will be generated.
- assertKindOf( $wantedClass,
$testedValue [, $failureMessage] )
- Die with a failure message if the specified testedValue is
not an instance of the specified wantedClass or one of its
derivatives. If the optional failureMessage is not given, one will be
generated.
- assertMatches( $wantedRegexp,
$testedValue [, $failureMessage] )
- Die with a failure message if the specified tested value
doesn't match the specified wanted regular expression. If the optional
failureMessage is not given, one will be generated.
- assertNoException( \&code[,
$failureMessage ] )
- Evaluate the specified coderef, and die with a failure
message if it generates an exception. If the optional failureMessage is
not given, one will be generated.
- assertNot( $value[,
$failureMessage ] )
- Die with a failure message if the specified value is
true. If the optional failureMessage is not given, one will be
generated.
- assertNotRef( $testedValue[,
$failureMessage ] )
- Die with a failure message if the specified testedValue is
a reference of any kind. If the optional failureMessage is not given, one
will be generated.
- assertRef( $wantedType,
$testedValue [, $failureMessage] )
- Die with a failure message if the specified testedValue is
not of the specified wantedType. The wantedType can either be a ref-type
like 'ARRAY' or 'GLOB' or a package name for testing object classes. If
the optional failureMessage is not given, one will be generated.
- assertUndef( $value[,
$failureMessage ] )
- Die with a failure message if the specified value is
defined. If the optional failureMessage is not given, one will be
generated.
- fail( [$failureMessage] )
- Die with a failure message unconditionally. If the optional
failureMessage is not given, a generic failure message will be used
instead.
Private Functions¶
- _CountAssertion()
- Add 1 to the count of assertions run in the current counter
frame.
- _CountSuccess()
- Add 1 to the count of successful assertions in the current
counter frame.
- _PopAssertionCounter()
- Remove the current assertion counter, and return a list of
the number of assertions run, and the number of assertions which
succeeded.
- _PushAssertionCounter()
- Add a pair of assertion counters to the stack. Assertion
counters are used to count assertion runs/successes, and this adds a level
in case of recursive runTests() calls.
Protected Functions¶
- _prepSuite( @tests )
- Split the specified array of test hashrefs into three
arrays: setupFuncs, tests, and teardownFuncs. Return references to the
three arrays.
- _runTests( \@setupFuncs, \@tests, \@teardownFuncs
)
- Run the specified tests, running any
setupFuncs before each one, and any teardownFuncs after each
one.
Skip Functions¶
- skipAll( [$message] )
- Skip all the remaining tests, optionally outputting a
message as to why the they were skipped.
- skipOne( [$message] )
- Skip the rest of this test, optionally outputting a message
as to why the rest of the test was skipped.
Test Data Functions¶
- loadTestData( $filename )
- Load key/data pairs from a data file that was saved from
previous tests. Returns a reference to a hash of data items.
- saveTestData( $filename,
%datahash )
- Save the key/value pairs in %datahash
to a file with the specified filename for later loading via
loadTestData().