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

NAME

Test::ParallelSubtest - fork subtests to run in parallel

SYNOPSIS

  use Test::More tests => 2;
  use Test::ParallelSubtest max_parallel => 8;

  bg_subtest test_one => sub {
      # tests here run in a sub-process
  };

  bg_subtest test_two => sub {
      # tests here run in another sub-process
  };

DESCRIPTION

This module allows a test script to run subtests (see "subtest" in Test::More) in the background, using a forked sub-processes for each subtest. Several background subtests can be run in parallel, saving time. Particularly handy if you have lots of tests that sleep for a second or two.

Background subtest output is buffered and merged, so that output from different child processes doesn't get mixed up. A test script using bg_subtest() should produce exactly the same results as it would if the bg_subtest() calls were replaced with subtest() calls, subject to a few "LIMITATIONS".

FUNCTIONS

The following functions are exported by default.

bg_subtest
    bg_subtest $name => \&code;

As "subtest" in Test::More, except that the subtest is run in the background in a forked sub-process. The test script's execution continues immediately, while the child process runs the subtest. The results of the background subtest will be captured in the child process, and later passed to the parent process and merged.

If the fork() system call is not available then bg_subtest() just does a regular subtest().

bg_subtest_wait

Waits for all currently running bg_subtest child processes to complete, and merges the child process output and test results into the parent process.

There is an implicit call to bg_subtest_wait() each time any of the following occur:

  • execution enters or leaves a subtest()

  • done_testing() is called, see "done_testing" in Test::More

  • execution reaches the end of the test script

You do not normally need to call bg_subtest_wait() manually, but see "LIMITATIONS" below for why you might want to.

max_parallel
    my $old_max_parallel = max_parallel 8;

Gets (and optionally sets) the maximum number of background subtests that will be run in parallel. The default is 4.

If called without arguments, max_parallel() just returns the current value.

If an argument is passed it becomes the new value. The old value is returned.

If the parallel subtest limit is set to 0 then subtests will not be run in sub-processes and bg_subtest() will act just like subtest().

The limit can also be accessed directly as $Test::ParallelSubtest::MaxParallel, which allows you to localize a change:

   {
      # Lots of parallelism for this next bit.
      local $Test::ParallelSubtest::MaxParallel = 20;

      #...
   }

The parallel subtest limit can be set when Test::ParallelSubtest is imported:

   use Test::ParallelSubtest max_parallel => 10;

LIMITATIONS

bg_subtest return value doesn't indicate pass/fail

The return value of subtest() tells you whether or not the subtest passed, but bg_subtest() can't do that because it returns before the subtest is complete.

bg_subtest() returns false when it launches the subtest in a child process.

bg_subtest side effects are lost

Because bg_subtest() runs your code in a forked sub-process, any side effects of the code will not be visible in the parent process or other bg_subtest child processes.

Note however that you should not rely on bg_subtest() side effects being lost, since bg_subtest() reverts to running the subtest in the parent process if fork() is not working.

parent tests may complete before bg_subtests started earlier

If you run tests in the parent process while background subtests are running, then the parent process tests will take effect first. For example, consider the test script:

   subtest foo => sub {
       plan tests => 1;
       ok 1, 'foo inner';
   };
   ok 1 'bar';

   # prints:
   #      1..1
   #      ok 1 - foo inner
   #  ok 1 - foo
   #  ok 2 - bar

On the other hand, the equivalent bg_subtest script:

   bg_subtest foo => sub {
       plan tests => 1;
       ok 1, 'foo inner';
   };
   ok 1 'bar';

   # prints:
   #  ok 1 - bar
   #      1..1
   #      ok 1 - foo inner
   #  ok 2 - foo

This happens because the 'bar' test runs in the parent process before the parent merges the results of the background subtest. Out of order test results can be prevented by adding bg_subtest_wait() calls to the test script.

AUTHOR

Nick Cleaton, <nick@cleaton.net>

COPYRIGHT AND LICENSE

Copyright (C) 2010 by Nick Cleaton

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.0 or, at your option, any later version of Perl 5 you may have available.