.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sh \" Subsection heading
.br
.if t .Sp
.ne 5
.PP
\fB\\$1\fR
.PP
..
.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. | will give a
.\" real vertical bar. \*(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-|\(bv\*(Tr
.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\}
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
.\"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.hy 0
.if n .na
.\"
.\" 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::Group 3"
.TH Test::Group 3 "2008-01-07" "perl v5.8.8" "User Contributed Perl Documentation"
.SH "NAME"
Test::Group \- Group together related tests in a test suite
.SH "VERSION"
.IX Header "VERSION"
Test::Group version 0.11
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 2
\& use Test::More no_plan => 1;
\& use Test::Group;
.Ve
.PP
.Vb 6
\& test "hammering the server" => sub {
\& ok(I_can_connect);
\& for(1..1000) {
\& ok(I_can_make_a_request);
\& }
\& }; # Don't forget the semicolon here!
.Ve
.PP
.Vb 6
\& test "this test group will fail", sub {
\& ok 1, "sub test blah";
\& is "foo", "bar"; # Oops!
\& ok 1;
\& like "blah blah blah", qr/bla/;
\& };
.Ve
.PP
.Vb 4
\& test "this test will fail but the suite will proceed", sub {
\& pass;
\& die;
\& };
.Ve
.PP
.Vb 4
\& test "a test with TODO in the name is marked TODO" => sub {
\& pass("this part is done");
\& fail("but I'm not finished with this one yet");
\& };
.Ve
.PP
.Vb 7
\& {
\& local $TODO = "Test::More's good old method also works";
\& test "this test is not finished yet" => sub {
\& pass;
\& fail;
\& };
\& };
.Ve
.PP
.Vb 2
\& # Don't catch exceptions raised in test groups later on
\& Test::Group->dont_catch_exceptions;
.Ve
.PP
.Vb 2
\& # log caught exceptions in /tmp/log
\& Test::Group->logfile("/tmp/log");
.Ve
.PP
.Vb 6
\& # skip the next group of test
\& skip_next_test "network not available" if (! Network->available());
\& test "bla", sub {
\& my $ftp = Net::FTP->new("some.host.name");
\& # ...
\& };
.Ve
.PP
.Vb 1
\& begin_skipping_tests "reason";
.Ve
.PP
.Vb 3
\& test "this test will not run" => sub {
\& # ...
\& };
.Ve
.PP
.Vb 1
\& end_skipping_tests;
.Ve
.PP
.Vb 2
\& # from now on, skip all tests whose names do not match /bla/
\& test_only qr/bla/;
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
Fed up with counting tests to discover what went wrong in your last
test run? Tired of squinting at your test source to find out where on
earth the faulty test predicate is called, and what it is supposed to
check for? Then this module is for you!
.PP
\&\fITest::Group\fR allows for grouping together related tests in a
standard \fITest::More\fR\-style script. (If you are not already familiar
with Test::More, now would be the time to go take a look.)
\&\fITest::Group\fR provides a bunch of maintainability and scalability
advantages to large test suites:
.IP "\(bu" 4
related tests can be grouped and given a name. The intent of the test
author is therefore made explicit with much less effort than would be
needed to name all the individual tests;
.IP "\(bu" 4
the test output is much shorter and more readable: only failed
subtests show a diagnostic, while test groups with no problems inside
produce a single friendly \f(CW\*(C`ok\*(C'\fR line;
.IP "\(bu" 4
no more tedious test counting: running an arbitrarily large or
variable number of tests (e.g. in loops) is now hassle-free and
doesn't clutter the test output.
.PP
Authors of \fITest::*\fR modules may also find \fITest::Group\fR of
interest, because it allows for composing several Test::More
predicates into a single one (see \*(L"Reflexivity\*(R").
.SH "FEATURES"
.IX Header "FEATURES"
.Sh "Blocking Exceptions"
.IX Subsection "Blocking Exceptions"
By default, calls to \*(L"die\*(R" in perlfunc and other exceptions from within
a test group cause it to fail and terminates execution of the group,
but does not terminate whole script. This relieves the programmer
from having to worry about code that may throw in tests.
.PP
This behavior can be disabled totally using \*(L"dont_catch_exceptions\*(R".
Exceptions can also be trapped as usual using \*(L"eval\*(R" in perlfunc or
otherwise from inside a group, in which case the test code of course
has full control on what to do next (this is how one should test error
management, by the way).
.PP
When Test::Group is set to block errors (the default setting, see also
\&\*(L"catch_exceptions\*(R"), the error messages are displayed as part of the
test name, which some may not find very readable. Therefore, one can
use a \*(L"logfile\*(R" instead.
.Sh "Skipping Groups"
.IX Subsection "Skipping Groups"
\&\fITest::Group\fR can skip single test groups or a range of them
(consecutive or matched by a regex), which helps shortening the debug
cycle even more in test-driven programming. When a test group is
skipped, the code within it is simply not executed, and the test is
marked as skipped wrt Test::Builder. See \*(L"skip_next_test\*(R",
\&\*(L"skip_next_tests\*(R", \*(L"begin_skipping_tests\*(R", \*(L"end_skipping_tests\*(R"
and \*(L"test_only\*(R" for details.
.Sh "Reflexivity"
.IX Subsection "Reflexivity"
Test groups integrate with Test::Builder by acting as a single big
test; therefore, \fITest::Group\fR is fully reflexive. A particularly
attractive consequence is that constructing new Test::More
predicates is straightforward with \fITest::Group\fR. For example,
.PP
.Vb 1
\& use Test::Group;
.Ve
.PP
.Vb 8
\& sub foobar_ok {
\& my ($text, $name) = @_;
\& $name ||= "foobar_ok";
\& test $name => sub {
\& like($text, qr/foo/, "foo ok");
\& like($text, qr/bar/, "bar ok");
\& };
\& }
.Ve
.PP
defines a new test predicate \fIfoobar_ok\fR that will \s-1DWIM\s0 regardless of
the caller's testing style: for \*(L"classical\*(R" Test::Simple or
Test::More users, \fIfoobar_ok\fR will act as just another \fI*_ok\fR
predicate (in particular, it always counts for a single test, honors
\&\*(L"\s-1TODO:\s0 \s-1BLOCK\s0\*(R" in Test::More constructs, etc); and of course, users of
\&\fITest::Group\fR can freely call \fIfoobar_ok\fR from within a group.
.Sh "\s-1TODO\s0 Tests"
.IX Subsection "TODO Tests"
As shown in \*(L"\s-1SYNOPSIS\s0\*(R", Test::More's concept of \s-1TODO\s0 tests is
supported by \fITest::Group\fR: a group is in \s-1TODO\s0 state if the \f(CW$TODO\fR
variable is set by the time it starts, or if the test name contains
the word \f(CW\*(C`TODO\*(C'\fR. Note, however, than setting \f(CW$TODO\fR from \fBinside\fR
the test group (that is, \fBafter\fR the group starts) will not do what
you mean:
.PP
.Vb 5
\& test "something" => sub {
\& local $TODO = "this test does not work yet";
\& pass; # GOTCHA!
\& fail;
\& };
.Ve
.PP
Here \f(CW\*(C`pass\*(C'\fR is an unexpected success, and therefore the whole test
group will report a \s-1TODO\s0 success despite the test not actually being a
success (that is, it would \fBalso\fR be defective if one were to comment
out the \f(CW\*(C`local $TODO\*(C'\fR line). This semantics, on the other hand,
DWIMs for marking a \fBportion\fR of the test group as \s-1TODO:\s0
.PP
.Vb 7
\& test "something" => sub {
\& pass;
\& {
\& local $TODO = "this part does not work yet";
\& fail;
\& }
\& };
.Ve
.PP
Finally, there is a subtle gotcha to be aware of when setting \f(CW$TODO\fR
outside a test group (that's the second one, so maybe you should not
do that to begin with). In this case, the value of \f(CW$TODO\fR is set to
undef \fBinside\fR the group. In other words, this test (similar to the
one to be found in \*(L"\s-1SYNOPSIS\s0\*(R") will succeed as expected:
.PP
.Vb 9
\& {
\& local $TODO = "not quite done yet";
\& test "foo" => sub {
\& fail;
\& pass; # NOT an unexpected success, as
\& # this is simply a subtest of the whole
\& # test "foo", which will fail.
\& };
\& }
.Ve
.Sh "\s-1FUNCTIONS\s0"
.IX Subsection "FUNCTIONS"
All functions below are intended to be called from the test
script. They are all exported by default.
.ie n .IP "\fItest($name, \fI$groupsub\fI)\fR" 4
.el .IP "\fItest($name, \f(CI$groupsub\fI)\fR" 4
.IX Item "test($name, $groupsub)"
Executes \fI$groupsub\fR, which must be a reference to a subroutine, in a
controlled environment and groups the results of all
Test::Builder\-style subtests launched inside into a single call to
\&\*(L"ok\*(R" in Test::Builder, regardless of their number. If the test group is
to be skipped (as discussed in \*(L"Skipping Groups\*(R"), calls
\&\*(L"skip\*(R" in Test::Builder once instead.
.Sp
In case the test group is \fBnot\fR skipped, the first parameter to
\&\*(L"ok\*(R" in Test::Builder and the value of the \s-1TODO\s0 string during same (see
\&\*(L"\s-1TODO:\s0 \s-1BLOCK\s0\*(R" in Test::More) are determined according to the following
algorithm:
.RS 4
.IP "1" 4
.IX Item "1"
if the test group terminates by throwing an exception, or terminates
normally but without calling any subtest, it fails.
.IP "2" 4
.IX Item "2"
otherwise, if any subtest failed outside of a \s-1TODO\s0 block, the group
fails.
.IP "3" 4
.IX Item "3"
otherwise, if any subtest \fBsucceeds\fR inside of a \s-1TODO\s0 block, the
group is flagged as an unexpected success.
.IP "4" 4
.IX Item "4"
otherwise, if any subtest fails inside of a \s-1TODO\s0 block, the group
results in a \s-1TODO\s0 (excused) failure.
.IP "5" 4
.IX Item "5"
otherwise, the test group managed to avert all hazards and is a
straight success (tada!!).
.RE
.RS 4
.Sp
If any sub-tests failed in \fI$groupsub\fR, diagnostics will be
propagated using \*(L"diag\*(R" in Test::Builder as usual.
.Sp
The return value of \fItest\fR is 1 if the test group is a success
(including a \s-1TODO\s0 unexpected success), 0 if it is a failure (including
a \s-1TODO\s0 excused failure), and undef if the test group was skipped.
.RE
.IP "\fIskip_next_tests\fR" 4
.IX Item "skip_next_tests"
.Vb 2
\& skip_next_tests 5;
\& skip_next_tests 5, "reason";
.Ve
.Sp
Skips the 5 following group of tests. Dies if we are currently
skipping tests already.
.IP "\fIskip_next_test\fR" 4
.IX Item "skip_next_test"
.Vb 2
\& skip_next_test;
\& skip_next_test "reason";
.Ve
.Sp
Equivalent to:
.Sp
.Vb 2
\& skip_next_tests 1;
\& skip_next_tests 1, "reason";
.Ve
.IP "\fIbegin_skipping_tests\fR" 4
.IX Item "begin_skipping_tests"
.Vb 2
\& begin_skipping_tests
\& begin_skipping_tests "reason";
.Ve
.Sp
Skips all subsequent groups of tests until blocked by
\&\*(L"end_skipping_tests\*(R". Dies if we are currently skipping tests
already.
.IP "\fIend_skipping_tests\fR" 4
.IX Item "end_skipping_tests"
Cancels the effect of \*(L"begin_skipping_tests\*(R". Has no effect if we
are not currently skipping tests.
.IP "\fItest_only\fR" 4
.IX Item "test_only"
.Vb 3
\& test_only "bla()", "reason";
\& test_only qr/^bla/;
\& test_only sub { /bla/ };
.Ve
.Sp
Skip all groups of tests whose name does not match the criteria. The
criteria can be a plain string, a regular expression or a function.
.Sp
.Vb 1
\& test_only;
.Ve
.Sp
Resets to normal behavior.
.SH "CLASS METHODS"
.IX Header "CLASS METHODS"
A handful of class methods are available to tweak the behavior of this
module on a global basis. They are to be invoked like this:
.PP
.Vb 1
\& Test::Group->foo(@args);
.Ve
.IP "\fIverbose($level)\fR" 4
.IX Item "verbose($level)"
Sets verbosity level to \f(CW$level\fR, where 0 means quietest. For now only 0
and 1 are implemented.
.IP "\fI\fIcatch_exceptions()\fI\fR" 4
.IX Item "catch_exceptions()"
Causes exceptions thrown from within the sub reference passed to
\&\*(L"test\*(R" to be blocked; in this case, the test currently running will
fail but the suite will proceed. This is the default behavior.
.Sp
Note that \fIcatch_exceptions\fR only deals with exceptions arising
inside \fItest\fR blocks; those thrown by surrounding code (if any) still
cause the test script to terminate as usual unless other appropriate
steps are taken.
.IP "\fI\fIdont_catch_exceptions()\fI\fR" 4
.IX Item "dont_catch_exceptions()"
Reverses the effect of \*(L"catch_exceptions\*(R", and causes exceptions
thrown from a \*(L"test\*(R" sub reference to be fatal to the whole suite.
This only takes effect for test subs that run after
\&\fI\fIdont_catch_exceptions()\fI\fR returns; in other words this is \fBnot\fR a
whole-script pragma.
.IP "\fIlogfile($classstate_logfile)\fR" 4
.IX Item "logfile($classstate_logfile)"
Sets the log file for caught exceptions to \fI$classstate_logfile\fR.
From this point on, all exceptions thrown from within a text group
(assuming they are caught, see \*(L"catch_exceptions\*(R") will be written
to \fI$classstate_logfile\fR instead of being passed on to
\&\*(L"diag\*(R" in Test::More. This is very convenient with exceptions with a
huge text representation (say an instance of Error containing a
stack trace).
.SH "BUGS"
.IX Header "BUGS"
This class uses a somewhat unhealthy dose of black magic to take over
control from Test::Builder when running inside a \*(L"test\*(R" group
sub. While the temporary re-blessing trick used therein is thought to
be very robust, it is not very elegant. Some kind of plugin mechanism
for Test::Builder\->new should be designed, implemented and used
instead.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
Test::Simple, Test::More, Test::Builder, and friends
.PP
The \f(CW\*(C`perl\-qa\*(C'\fR project, .
.Sh "Similar modules on \s-1CPAN\s0"
.IX Subsection "Similar modules on CPAN"
Test::Class can be used to turn a test suite into a full-fledged
object class of its own, in xUnit style. It also happens to support a
similar form of test grouping using the \f(CW\*(C`:Test(no_plan)\*(C'\fR or \f(CW\*(C`:Tests\*(C'\fR
attributes. Switching over to \fITest::Class\fR will make a test suite
more rugged and provide a number of advantages, but it will also
dilute the \*(L"quick\-and\-dirty\*(R" aspect of .t files somewhat. This may or
may not be what you want: for example, the author of this module
enjoys programming most when writing tests, because the most infamous
Perl hacks are par for the course then :\-). Anyway \s-1TIMTOWTDI\s0, and
\&\fITest::Group\fR is a way to reap some of the benefits of \fITest::Class\fR
(e.g. running only part of the test suite) without changing one's
programming style too much.
.SH "AUTHORS"
.IX Header "AUTHORS"
Dominique Quatravaux
.PP
Nicolas M. Thie\*'ry
.SH "LICENSE"
.IX Header "LICENSE"
Copyright (C) 2004 by \s-1IDEALX\s0
.PP
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.1 or,
at your option, any later version of Perl 5 you may have available.