The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Name

Test::Stream::Subtest - Encapsulate subtest start, run, and finish.

Synopsys

    use Test::More;

    subtest 'An example subtest' => sub {
        pass("This is a subtest");
        pass("So is this");
    };

    done_testing;

DESCRIPTION

subtest name => sub { ... } runs the code as its own little test with its own plan and its own result. The main test counts this as a single test using the result of the whole subtest to determine if its ok or not ok.

COMPLETE EXAMPLE

  use Test::More tests => 3;

  pass("First test");

  subtest 'An example subtest' => sub {
      plan tests => 2;

      pass("This is a subtest");
      pass("So is this");
  };

  pass("Third test");

This would produce.

  1..3
  ok 1 - First test
      # Subtest: An example subtest
      1..2
      ok 1 - This is a subtest
      ok 2 - So is this
  ok 2 - An example subtest
  ok 3 - Third test

SKIPPING ALL TESTS IN A SUBTEST

A subtest may call skip_all. No tests will be run, but the subtest is considered a skip.

  subtest 'skippy' => sub {
      plan skip_all => 'cuz I said so';
      pass('this test will never be run');
  };

Returns true if the subtest passed, false otherwise.

SKIPPING ALL IN A BEGIN BLOCK

Sometimes you want to run a file as a subtest:

    subtest foo => sub { do 'foo.pl' };

where foo.pl;

    use Test::More skip_all => "won't work";

This will work fine, but will issue a warning. The issue is that the normal flow control method will not work inside a BEGIN block. The use Test::More statement is run in a BEGIN block. As a result an exception is thrown instead of the normal flow control. In most cases this works fine.

A case like this however will have issues:

    subtest foo => sub {
        do 'foo.pl'; # Will issue a skip_all

        # You would expect the subtest to stop, but the 'do' captures the
        # exception, as a result the following statement does execute.

        ok(0, "blah");
    };

You can work around this by cheking the return from do, along with $@, or you can alter foo.pl so that it does this:

    use Test::More;
    plan skip_all => 'broken';

When the plan is issues outside of the BEGIN block it works just fine.

SUBTEST PLANNING

Due to how subtests work, you may omit a plan if you desire. This adds an implicit done_testing() to the end of your subtest. The following two subtests are equivalent:

  subtest 'subtest with implicit done_testing()' => sub {
      ok 1, 'subtests with an implicit done testing should work';
      ok 1, '... and support more than one test';
      ok 1, '... no matter how many tests are run';
  };

  subtest 'subtest with explicit done_testing()' => sub {
      ok 1, 'subtests with an explicit done testing should work';
      ok 1, '... and support more than one test';
      ok 1, '... no matter how many tests are run';
      done_testing();
  };

SUBTESTS AND CONCURRENCY

STARTING A SUBTEST IN A NEW PROCESS

This works fine:

    use Test::More;
    use Test::Stream 'concurrency';

    my $pid = fork();
    if (!$pid) {
        subtest foo => sub {
            ok(1, "inside foo");
        };
        exit 0;
    }
    waitpid($pid, 0);

    done_testing;

Per usual, always observe proper forking practices, be sure to exit your process when you are done with it.

STARTING A SUBTEST IN A NEW THREAD

This works fine:

    use threads;
    use Test::More;

    my $thr = threads->create(sub {
        subtest foo => sub {
            ok(1, "inside foo");
        };
    };

    $thr->join;

    done_testing;

Per usual, always observe proper threading practices, call join() on your thread.

STARTING A NEW PROCESS INSIDE A SUBTEST

This works fine:

    use Test::More;
    use Test::Stream 'concurrency';

    subtest foo => sub {
        my $pid = fork();
        if (!$pid) {
            ok(1, "inside child $$");
            exit 0;
        }

        ok(1, "In parent $$");

        waitpid($pid, 0);
    };

    done_testing;

If you start a new process inside a subtest, you MUST end the process BEFORE the subtest completes. This means calling exit() before the subtest subroutine ends in the child process. You MUST also wait on the child process BEFORE the subroutine ends in the parent.

If you forget to end the new process or thread in the child, the subtest will end it for you, and throw an exception in the parent. If you fail to wait or join in the parent, an exception will be thrown for any event that is recieved after the subtest ends.

STARTING A NEW THREAD INSIDE A SUBTEST

This works fine:

    use threads;
    use Test::More;

    subtest foo => sub {
        my $thr = threads->create(sub {
            ok(1, "inside child $$");
            exit 0;
        });

        ok(1, "In parent $$");
        $thr->join;
    };

    done_testing;

You MUST join all the threads created in the subtest BEFORE the subtest subroutine ends.

SOURCE

The source code repository for Test::More can be found at http://github.com/Test-More/test-more/.

MAINTAINER

Chad Granum <exodist@cpan.org>

AUTHORS

The following people have all contributed to the Test-More dist (sorted using VIM's sort function).

Chad Granum <exodist@cpan.org>
Fergal Daly <fergal@esatclear.ie>>
Mark Fowler <mark@twoshortplanks.com>
Michael G Schwern <schwern@pobox.com>
唐鳳

COPYRIGHT

There has been a lot of code migration between modules, here are all the original copyrights together:

Test::Stream
Test::Stream::Tester

Copyright 2015 Chad Granum <exodist7@gmail.com>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://www.perl.com/perl/misc/Artistic.html

Test::Simple
Test::More
Test::Builder

Originally authored by Michael G Schwern <schwern@pobox.com> with much inspiration from Joshua Pritikin's Test module and lots of help from Barrie Slaymaker, Tony Bowden, blackstar.co.uk, chromatic, Fergal Daly and the perl-qa gang.

Idea by Tony Bowden and Paul Johnson, code by Michael G Schwern <schwern@pobox.com>, wardrobe by Calvin Klein.

Copyright 2001-2008 by Michael G Schwern <schwern@pobox.com>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://www.perl.com/perl/misc/Artistic.html

Test::use::ok

To the extent possible under law, 唐鳳 has waived all copyright and related or neighboring rights to Test-use-ok.

This work is published from Taiwan.

http://creativecommons.org/publicdomain/zero/1.0

Test::Tester

This module is copyright 2005 Fergal Daly <fergal@esatclear.ie>, some parts are based on other people's work.

Under the same license as Perl itself

See http://www.perl.com/perl/misc/Artistic.html

Test::Builder::Tester

Copyright Mark Fowler <mark@twoshortplanks.com> 2002, 2004.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.