NAME

Test::Group - Group together related tests in a test suite

VERSION

Test::Group version 0.02

SYNOPSIS

use Test::More no_plan => 1;
use Test::Group;

test "hammering the server" => sub {
    ok(I_can_connect);
    for(1..1000) {
       ok(I_can_make_a_request);
    }
}; # Don't forget the semicolon here!
    test "this test group will fail", sub {
        ok 1, "sub test blah";
        is "foo", "bar"; # Oops!
        ok 1;
        like   "blah blah blah", qr/bla/;
	};

    test "this test will fail but the suite will proceed", sub {
        pass;
        die;
    };
    # Don't catch exceptions raised in test groups later on
    Test::Group->dont_catch_exceptions;

    # log caught exceptions in /tmp/log
    Test::Group->logfile("/tmp/log");

    # 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");
        # ...
    };

    begin_skipping_tests "reason";
    # ...
    # all groups of tests here are ignored
    # ...
    end_skipping_tests;

    # from now on, skip all tests whose names do not match /bla/
    test_only qr/bla/;

DESCRIPTION

Fed up with counting tests to find out 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!

Test::Group allows for grouping together related tests in a standard Test::Builder script. This provides a bunch of maintainability and scalability advantages to large test suites:

  • 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;

  • 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 ok line;

  • no more tedious test counting: running an arbitrarily large or variable number of tests (e.g. in loops) is made easy, without cluttering the display nor making the test counting painful;

  • Test::Group can skip whole groups of tests or even a range of groups matched by a regex, which helps shortening the debug cycle even more in test-driven programming.

Test::Group is built atop Test::Builder and plays happily with Test::More and friends. If you are not already familiar with Test::More, now would be the time to go take a look.

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 :Tests attribute (introduced in version 0.10). Switching over to Test::Class will make a test suite more rugged and provide a number of advantages, but it will also dilute the "quick-and-dirty" 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 TIMTOWTDI, and Test::Group is a way to reap some of the benefits of Test::Class (e.g. running only part of the test suite) without changing one's programming style too much.

FUNCTIONS

All functions below are intended to be called from the test script. They are all exported by default.

test($name, $groupsub)

Executes $groupsub, which must be a reference to a subroutine, in a controlled environment and groups the results of all Test::Builder-style tests launched inside into a single call to "ok" in Test::Builder, regardless of their number.

outputs a summary of the tests executed inside. From the point of view of Test::Builder, a call to test() will translate to a single call to "ok" in Test::Builder regardless of the number of invocations of test assertions that were made from inside $groupsub; said grouped test succeeds if and only if all conditions below are met:

  • no test assertion in $groupsub failed;

  • at least one test assertion in $groupsub passed;

  • no exception was thrown.

If any sub-tests failed in $groupsub, diagnostics will be propagated using "diag" in Test::Builder as usual. The return value of test is true if at least one subtest succeeded

skip_next_tests
skip_next_tests 5;
skip_next_tests 5, "reason";

Skips the 5 following group of tests. Dies if we are currently skipping tests already.

skip_next_test
skip_next_test;
skip_next_test "reason";

Equivalent to:

skip_next_tests 1;
skip_next_tests 1, "reason";
begin_skipping_tests
begin_skipping_tests
begin_skipping_tests "reason";

Skips all subsequent groups of tests until blocked by "end_skipping_tests". Dies if we are currently skipping tests already.

end_skipping_tests

Cancels the effect of "begin_skipping_tests". Has no effect if we are not currently skipping tests.

test_only
test_only "bla()", "reason";
test_only qr/^bla/;
test_only sub { /bla/ };

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.

test_only;

Resets to normal behavior.

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:

Test::Group->foo(@args);
verbose($level)

Sets verbosity level to $level, where 0 means quietest. For now only 0 and 1 are implemented.

catch_exceptions()

Causes exceptions thrown from within the sub reference passed to "test" to be blocked; in this case, the test currently running will fail but the suite will proceed. This is the default behavior.

Note that catch_exceptions only deals with exceptions arising inside test blocks; those thrown by surrounding code (if any) still cause the test script to terminate as usual unless other appropriate steps are taken.

dont_catch_exceptions()

Reverses the effect of "catch_exceptions", and causes exceptions thrown from a "test" sub reference to be fatal to the whole suite. This only takes effect for test subs that run after dont_catch_exceptions() returns; in other words this is not a whole-script pragma.

failed()

Returns the number of test groups failed so far.

logfile($logfile)

Sets the log file for caught exceptions to $logfile. From this point on, all exceptions thrown from within a text group (assuming they are caught, see "catch_exceptions") will be written to $logfile instead of being passed on to "diag" in Test::More. This is very convenient with exceptions with a huge text representation (say an instance of Error containing a stack trace).

BUGS

This class uses a somewhat unhealthy dose of black magic to take over control from Test::Builder when running inside a "test" 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.

SEE ALSO

Test::Simple, Test::More, Test::Builder, and friends; the per-qa mailing list (<>).

AUTHORS

Dominique Quatravaux <dom@idealx.com>

Nicolas M. Thiéry <nthiery@users.sf.net>

LICENSE

Copyright (C) 2004 by IDEALX <http://www.idealx.com>

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.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 699:

Non-ASCII character seen before =encoding in 'Thiéry'. Assuming UTF-8