.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Test::SimpleUnit 3pm" .TH Test::SimpleUnit 3pm "2011-11-15" "perl v5.14.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Test::SimpleUnit \- Simplified Perl unit\-testing framework .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 5 \& use Test::SimpleUnit qw{:functions}; \& runTests( \& {name => "test1", test => sub {...}}, \& {name => "testN", test => sub {...}} \& ); .Ve .SH "EXAMPLE" .IX Header "EXAMPLE" .Vb 1 \& 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 => \*(Aqrequire\*(Aq, \& 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(\*(Aq:myfuncs\*(Aq) } "Failed to import :myfuncs"; \& \& # Make sure calling \*(Aqimport()\*(Aq actually imported the functions \& assertRef \*(AqCODE\*(Aq, *::myfunc{CODE}; \& assertRef \*(AqCODE\*(Aq, *::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 => \*(Aqsetup\*(Aq, \& test => sub { \& # If the previous test didn\*(Aqt finish, it\*(Aqs 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 => \*(Aqteardown\*(Aq, \& test => sub { \& undef $Instance; \& }, \& }, \& \& # Test the connect() and disconnect() methods \& { \& name => \*(Aqconnect() and disconnect()\*(Aq, \& 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 => \*(Aqsetup\*(Aq, \& func => sub { \& MyClass::prepNetwork(); \& }, \& }, \& \& # Now override the previous setup function with a new one that does \& # a connect() before each remaining test. \& { \& name => \*(Aqsetup\*(Aq, \& test => sub { \& $Instance = new MyClass; \& $Instance\->connect; \& }, \& } \& \& # Same thing for teardown/disconnect() \& { \& name => \*(Aqteardown\*(Aq, \& test => sub { \& $Instance\->disconnect; \& undef $Instance; \& }, \& }, \& \& ... \& \& ); \& \& runTests( @testSuite ); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This is a simplified Perl unit-testing framework for creating unit tests to be run either standalone or under Test::Harness. .SS "Testing" .IX Subsection "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. .PP If errors occur while running tests via the 'make test' method, you can get more verbose output about the test run by adding \f(CW\*(C`TEST_VERBOSE=1\*(C'\fR to the end of the \&\f(CW\*(C`make\*(C'\fR invocation: .PP .Vb 1 \& $ make test TEST_VERBOSE=1 .Ve .PP If you want to display only the messages caused by failing assertions, you can add a \f(CW\*(C`VERBOSE=1\*(C'\fR to the end of the \f(CW\*(C`make\*(C'\fR invocation instead: .PP .Vb 1 \& $ make test VERBOSE=1 .Ve .SS "Test Suites" .IX Subsection "Test Suites" A test suite is one or more test cases, each of which tests a specific unit of functionality. .SS "Test Cases" .IX Subsection "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. .PP You may wish to split test cases up into separate files under a \f(CW\*(C`t/\*(C'\fR directory so they will run under a Test::Harness\-style \f(CW\*(C`make test\*(C'\fR. .SS "Tests" .IX Subsection "Tests" A test is a hashref which contains two key-value pairs: a \fIname\fR key with the name of the test as the value, and a code reference under a \fItest\fR key: .PP .Vb 4 \& { \& name => \*(AqThis is the name of the test\*(Aq, \& test => sub { ...testing code... } \& } .Ve .PP Each test's \f(CW\*(C`test\*(C'\fR 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. .SS "Setup and Teardown Functions" .IX Subsection "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 \s-1EXAMPLE\s0 section for an example of how to use this. .PP 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. .PP The code reference value within a \fIsetup\fR or \fIteardown\fR test case can optionally be named \f(CW\*(C`func\*(C'\fR instead of \f(CW\*(C`test\*(C'\fR for clarity. If there are both \&\f(CW\*(C`func\*(C'\fR and \f(CW\*(C`test\*(C'\fR key-value pairs in a \fIsetup\fR or \fIteardown\fR case, the \&\f(CW\*(C`test\*(C'\fR pair is silently ignored. .SS "Saving Test Data" .IX Subsection "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 \&\fIsaveTestData()\fR function. In succeeding tests, it can be reloaded using the \fIloadTestData()\fR function. .SH "REQUIRES" .IX Header "REQUIRES" Carp, Data::Compare, Data::Dumper, Exporter, Fcntl, IO::File, IO::Handle, Scalar::Util .SH "EXPORTS" .IX Header "EXPORTS" Nothing by default. .PP This module exports several useful assertion functions for the following tags: .IP "\fB:asserts\fR" 4 .IX Item ":asserts" assert, assertNot, assertDefined, assertUndef, assertNoException, assertException, assertExceptionType, assertExceptionMatches, assertEquals, assertMatches, assertRef, assertNotRef, assertInstanceOf, assertKindOf, fail .IP "\fB:skips\fR" 4 .IX Item ":skips" skipOne, skipAll .IP "\fB:testFunctions\fR" 4 .IX Item ":testFunctions" runTests .IP "\fB:testdata\fR" 4 .IX Item ":testdata" loadTestData, saveTestData .IP "\fB:functions\fR" 4 .IX Item ":functions" All of the above. .SH "AUTHOR" .IX Header "AUTHOR" Michael Granger .PP Copyright (c) 1999\-2003 The FaerieMUD Consortium. All rights reserved. .PP 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) .SH "FUNCTIONS" .IX Header "FUNCTIONS" .ie n .IP "\fIAutoskipFailedDataLoad( \fI$trueOrFalse\fI )\fR" 4 .el .IP "\fIAutoskipFailedDataLoad( \f(CI$trueOrFalse\fI )\fR" 4 .IX Item "AutoskipFailedDataLoad( $trueOrFalse )" If set to a true value, any failure to reload test data via \fIloadTestData()\fR will cause the test to be skipped instead of running. .ie n .IP "\fIAutoskipFailedSetup( \fI$trueOrFalse\fI )\fR" 4 .el .IP "\fIAutoskipFailedSetup( \f(CI$trueOrFalse\fI )\fR" 4 .IX Item "AutoskipFailedSetup( $trueOrFalse )" If set to a true value, any failed setup functions will cause the test to be skipped instead of running. .ie n .IP "\fIAutoskipFailedTeardown( \fI$trueOrFalse\fI )\fR" 4 .el .IP "\fIAutoskipFailedTeardown( \f(CI$trueOrFalse\fI )\fR" 4 .IX Item "AutoskipFailedTeardown( $trueOrFalse )" If set to a true value, any failed teardown functions will cause the test to be skipped instead of running. .ie n .IP "\fIDebug( \fI$trueOrFalse\fI )\fR" 4 .el .IP "\fIDebug( \f(CI$trueOrFalse\fI )\fR" 4 .IX Item "Debug( $trueOrFalse )" If set to a true value, the test suite will be dumped to \s-1STDERR\s0 before running. .ie n .IP "\fIOutputHandle( \fI$handle\fI )\fR" 4 .el .IP "\fIOutputHandle( \f(CI$handle\fI )\fR" 4 .IX Item "OutputHandle( $handle )" Set the \fIhandle\fR 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 \fIrunTests()\fR from within an assertion. It defaults to \s-1STDOUT\s0, 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. .ie n .IP "\fIrunTests( \fI@testSuite\fI )\fR" 4 .el .IP "\fIrunTests( \f(CI@testSuite\fI )\fR" 4 .IX Item "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: .SS "Assertion Functions" .IX Subsection "Assertion Functions" .ie n .IP "\fIassert( \fI$value\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassert( \f(CI$value\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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. .ie n .IP "\fIassertDefined( \fI$value\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertDefined( \f(CI$value\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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. .ie n .IP "\fIassertEquals( \fI$wanted\fI, \f(CI$tested\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertEquals( \f(CI$wanted\fI, \f(CI$tested\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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 \s-1GLOB\s0, \s-1CODE\s0, or \s-1REF\s0 references. If the optional failureMessage is not given, one will be generated. .ie n .IP "\fIassertException( \e&code[, \fI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertException( \e&code[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "assertException( &code[, $failureMessage] )" Evaluate the specified \fIcoderef\fR, and die with a failure message if it does not generate an exception. If the optional \fIfailureMessage\fR is not given, one will be generated. .ie n .IP "\fIassertExceptionMatches( \e&code, \fI$regex\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertExceptionMatches( \e&code, \f(CI$regex\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "assertExceptionMatches( &code, $regex[, $failureMessage] )" Evaluate the specified \fIcoderef\fR, and die with a failure message if it does not generate an exception which matches the specified \fIregex\fR. If the optional \fIfailureMessage\fR is not given, one will be generated. .ie n .IP "\fIassertExceptionType( \e&code, \fI$type\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertExceptionType( \e&code, \f(CI$type\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "assertExceptionType( &code, $type[, $failureMessage] )" Evaluate the specified \fIcoderef\fR, and die with a failure message if it does not generate an exception which is an object blessed into the specified \&\fItype\fR or one of its subclasses (ie., the exception must return true to \&\f(CW\*(C`$exception\-\*(C'\fRisa($type)>. If the optional \fIfailureMessage\fR is not given, one will be generated. .ie n .IP "\fIassertInstanceOf( \fI$wantedClass\fI, \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertInstanceOf( \f(CI$wantedClass\fI, \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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. .ie n .IP "\fIassertKindOf( \fI$wantedClass\fI, \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertKindOf( \f(CI$wantedClass\fI, \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "assertKindOf( $wantedClass, $testedValue[, $failureMessage] )" Die with a failure message if the specified testedValue is not an instance of the specified wantedClass \fBor\fR one of its derivatives. If the optional failureMessage is not given, one will be generated. .ie n .IP "\fIassertMatches( \fI$wantedRegexp\fI, \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertMatches( \f(CI$wantedRegexp\fI, \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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. .ie n .IP "\fIassertNoException( \e&code[, \fI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertNoException( \e&code[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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. .ie n .IP "\fIassertNot( \fI$value\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertNot( \f(CI$value\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "assertNot( $value[, $failureMessage] )" Die with a failure message if the specified value \fBis\fR true. If the optional failureMessage is not given, one will be generated. .ie n .IP "\fIassertNotRef( \fI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertNotRef( \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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. .ie n .IP "\fIassertRef( \fI$wantedType\fI, \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertRef( \f(CI$wantedType\fI, \f(CI$testedValue\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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 '\s-1ARRAY\s0' or '\s-1GLOB\s0' or a package name for testing object classes. If the optional failureMessage is not given, one will be generated. .ie n .IP "\fIassertUndef( \fI$value\fI[, \f(CI$failureMessage\fI] )\fR" 4 .el .IP "\fIassertUndef( \f(CI$value\fI[, \f(CI$failureMessage\fI] )\fR" 4 .IX Item "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. .IP "\fIfail( [$failureMessage] )\fR" 4 .IX Item "fail( [$failureMessage] )" Die with a failure message unconditionally. If the optional \&\fIfailureMessage\fR is not given, a generic failure message will be used instead. .SS "Private Functions" .IX Subsection "Private Functions" .IP "\fI\fI_CountAssertion()\fI\fR" 4 .IX Item "_CountAssertion()" Add 1 to the count of assertions run in the current counter frame. .IP "\fI\fI_CountSuccess()\fI\fR" 4 .IX Item "_CountSuccess()" Add 1 to the count of successful assertions in the current counter frame. .IP "\fI\fI_PopAssertionCounter()\fI\fR" 4 .IX Item "_PopAssertionCounter()" Remove the current assertion counter, and return a list of the number of assertions run, and the number of assertions which succeeded. .IP "\fI\fI_PushAssertionCounter()\fI\fR" 4 .IX Item "_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 \fIrunTests()\fR calls. .SS "Protected Functions" .IX Subsection "Protected Functions" .ie n .IP "\fI_prepSuite( \fI@tests\fI )\fR" 4 .el .IP "\fI_prepSuite( \f(CI@tests\fI )\fR" 4 .IX Item "_prepSuite( @tests )" Split the specified array of test hashrefs into three arrays: setupFuncs, tests, and teardownFuncs. Return references to the three arrays. .IP "\fI_runTests( \e@setupFuncs, \e@tests, \e@teardownFuncs )\fR" 4 .IX Item "_runTests( @setupFuncs, @tests, @teardownFuncs )" Run the specified \fItests\fR, running any \fIsetupFuncs\fR before each one, and any \fIteardownFuncs\fR after each one. .SS "Skip Functions" .IX Subsection "Skip Functions" .IP "\fIskipAll( [$message] )\fR" 4 .IX Item "skipAll( [$message] )" Skip all the remaining tests, optionally outputting a message as to why the they were skipped. .IP "\fIskipOne( [$message] )\fR" 4 .IX Item "skipOne( [$message] )" Skip the rest of this test, optionally outputting a message as to why the rest of the test was skipped. .SS "Test Data Functions" .IX Subsection "Test Data Functions" .ie n .IP "\fIloadTestData( \fI$filename\fI )\fR" 4 .el .IP "\fIloadTestData( \f(CI$filename\fI )\fR" 4 .IX Item "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. .ie n .IP "\fIsaveTestData( \fI$filename\fI, \f(CI%datahash\fI )\fR" 4 .el .IP "\fIsaveTestData( \f(CI$filename\fI, \f(CI%datahash\fI )\fR" 4 .IX Item "saveTestData( $filename, %datahash )" Save the key/value pairs in \fI\f(CI%datahash\fI\fR to a file with the specified \&\fIfilename\fR for later loading via \fIloadTestData()\fR.