NAME
Test::Workflow - Provide test grouping, reusability, and structuring such as RSPEC and cases.
DESCRIPTION
Test::Workflow provides tools for grouping and structuring tests. There is also a facility to write re-usable tests. Test::Workflow test files define classes. Tests within the files are defined as a type of method.
Test::Workflow provides an RSPEC implementation. This implementation includes describe
blocks, it
blocks, as well as before_each
, before_all
, after_each
, after_all
. There are even two new types: around_each
and around_all
.
Test::Workflow provides a cases workflow. This workflow allows you to create multiple cases, and multiple tests. Each test will be run under each case. This allows you to write a test that should pass under multiple conditions, then write a case that builds that specific condition.
Test::Workflow provides a way to 'inherit' tests. You can write classes that use Test::Workflow, and define test groups, but not run them. These classes can then be imported into as many test classes as you want. This is achieved with the with_tests
function.
Test::Workflow gives you control over the order in which test groups will be run. You can use the predefined 'random', 'ordered', or 'sort' settings. You may also provide your own ordering function. This is achieved using the test_sort
function.
SYNOPSIS
package
MyTest;
use
strict;
use
warnings;
use
Test::More;
use
Test::Workflow;
with_tests
qw/ Test::TemplateA Test::TemplateB /
;
test_sort
'rand'
;
# Tests can be at the package level
use_ok(
'MyClass'
);
tests
loner
=>
sub
{
my
$self
=
shift
;
ok( 1,
"1 is the loneliest number... "
);
};
tests
not_ready
=> (
todo
=>
"Feature not implemented"
,
code
=>
sub
{ ... },
);
tests
very_not_ready
=> (
skip
=>
"These tests will die if run"
code
=>
sub
{ ... },
);
run_tests();
done_testing();
RSPEC WORKFLOW
Here setup/teardown methods are declared in the order in which they are run, but they can really be declared anywhere within the describe block and the behavior will be identical.
describe
example
=>
sub
{
my
$self
=
shift
;
my
$number
= 0;
my
$letter
=
'A'
;
before_all
setup
=>
sub
{
$number
= 1 };
before_each
letter_up
=>
sub
{
$letter
++ };
# it() is an alias for tests()
it
check
=>
sub
{
my
$self
=
shift
;
is(
$letter
,
'B'
,
"Letter was incremented"
);
is(
$number
, 2,
"number was incremented"
);
};
after_each
reset
=>
sub
{
$number
= 1 };
after_all
teardown
=>
sub
{
is(
$number
, 1,
"number is back to 1"
);
};
describe
nested
=>
sub
{
# This nested describe block will inherit before_each and
# after_each from the parent block.
...
};
describe
maybe_later
=> (
todo
=>
"We might get to this"
,
code
=> { ... },
);
};
describe
addon
=>
sub
{
my
$self
=
shift
;
around_each
localize_env
=>
sub
{
my
$self
=
shift
;
my
(
$inner
) =
@_
;
local
%ENV
= (
%ENV
,
foo
=>
'bar'
);
$inner
->();
};
tests
foo
=>
sub
{
is(
$ENV
{foo},
'bar'
,
"in the localized environment"
);
};
};
CASE WORKFLOW
Cases are used when you have a test that you wish to run under several tests conditions. The following is a trivial example. Each test will be run once under each case. Beware! this will run (cases x tests), with many tests and cases this can be a huge set of actual tests. In this example 8 in total will be run.
Note: The 'cases' keyword is an alias to describe. case blocks can go into any workflow and will work as expected.
cases
check_several_numbers
=>
sub
{
my
$number
;
case
two
=>
sub
{
$number
= 2 };
case
four
=>
sub
{
$number
= 4 };
case
six
=>
sub
{
$number
= 6 };
case
eight
=>
sub
{
$number
= 8 };
tests
is_even
=>
sub
{
ok( !
$number
% 2,
"number is even"
);
};
tests
only_digits
=>
sub
{
like(
$number
,
qr/^\d+$/
i,
"number is all digits"
);
};
};
EXPORTS
- with_tests( @CLASSES )
-
Use tests defined in the specified classes.
- test_sort( sub { my @tests = @_; ...; return @tests })
- test_sort( 'sort' )
- test_sort( 'random' )
- test_sort( 'ordered' )
-
Declare how tests should be sorted.
- cases( name => sub { ... })
- cases( 'name', %params, code => sub { ... })
- describe( name => sub { ... })
- describe( 'name', %params, code => sub { ... })
-
Define a block that encapsulates workflow elements.
- tests( name => sub { ... })
- tests( 'name', %params, code => sub { ... })
- it( name => sub { ... })
- it( 'name', %params, code => sub { ... })
-
Define a test block.
- case( name => sub { ... })
- case( 'name', %params, code => sub { ... })
-
Define a case, each test will be run once per case that is defined at the same level (within the same describe or cases block).
- before_each( name => sub { ... })
- after_each( name => sub { ... })
- before_all( name => sub { ... })
- after_all( name => sub { ... })
-
These define setup and teardown functions that will be run around tests.
- around_each( name => sub { ... })
- around_all( name => sub { ... })
-
These are special additions to the setup and teardown methods. They are used like so:
around_each
localize_env
=>
sub
{
my
$self
=
shift
;
my
(
$inner
) =
@_
;
local
%ENV
= (
%ENV
,
foo
=>
'bar'
);
$inner
->();
};
- run_tests()
-
This will finalize the meta-data (forbid addition of new tests) and run the tests.
AUTHORS
Chad Granum exodist7@gmail.com
COPYRIGHT
Copyright (C) 2013 Chad Granum
Test-Workflow is free software; Standard perl license.
Test-Workflow is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.