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

NAME

Test::Dynamic - Automatic test counting for Test::More

VERSION

This documents version 1.3.3 of the Test::Dynamic module

SYNOPSIS

  use Test::More;
  use Test::Dynamic;

  my $tests = Test::Dynamic::count_tests
        (
         {
          filehandle => \*DATA,
          verbose    => 1,
          local      => [qw(compare_tables)]
          }
         );

  plan tests => $tests;

  __DATA__

DESCRIPTION

This module helps to count your tests for you in an automatic way. When you add or remove tests, Test::Dynamic will attempt to keep track of the total correct number for you.

Methods

count_tests

Creates a Test::Dynamic instance and attempts to count the number of tests performed in the supplied code. Note that this method is not exported by default.

Arguments

The count_tests method takes the following arguments:

filehandle

Mandatory argument. An open filehandle to the file that contains the tests you want to count. Usually, this is the same file you are already in. One way to provide your own file is to give the filehandle argument the value \*DATA. If you do so, you must also ensure that your script has a __DATA__ section at the bottom of it.

verbose

Optional argument, defaults to false. If true, detailed information is sent to stderr showing how many tests were found in each section, and generally allowing you to see how Test::Dynamic arrived at its final test count.

local

Optional, empty by default. Test::Dynamic looks for simple test commands such as cmp_ok and counts them as a single test. If you have your own tests, or subroutines that perform a test, you can add your own here which will be counted as a single test for purposes of counting. The input should be an arrayref of terms, for example:

  local => [qw/foo bar baz/]
skipuseline

Optional, empty by default. If set, all lines until one that begins with 'use Test::Dynamic' are skipped.

USAGE

Basic test counting

Test::Dynamic works by looking for basic test methods, such as cmp_ok(), but allows you to define your own methods as well with the local argument. Test counting stops then __DATA__, __END__, or the word exit;" is found. All test methods must be called with parens: pass("xxx"); will work, but pass "xxx"; will not. Test methods must appear at the start of the line, although whitespace is allowed, of course.

Subroutines

An important part of counting the tests is keeping track of which subroutines are used and where. Since subroutines can be nested within each other, Test::Dynamic needs to know exactly where a subroutine ends. After the closing brace in a subroutine, add the following:

  ## end of subroutine_name

For example:

  sub foobar {
    my $name = shift;
    return Baz->mangle($name);
  } ## end of foobar

Adjusting the current test count

The number of tests that a subroutine within the script calls is kept track of, and each call to that subroutine increments the number of tests by the amount in that subroutine. For example:

  cmp($x, $y, "Foo and bar are equal");

  pickle();

  sub pickle {
    pass("Pickle is ok");
    is_deeply($d,$e, "Complex hashrefs look the same");
  }

In the above, Test::Dynamic will count the number of tests as three.

Comments with two hashes can be used to further control the behavior. To tell Test::Dynamic that a particular line of code will run more than one test, such as in a loop, you can use the TESTCOUNT parameter:

  for my $x (1..10) {
    like($foo{$x}, qr{pickle}, "Item $x contains a pickle"); ## TESTCOUNT * 10
  }

Any of the basic math multipliers can be used: addition, subtraction, multiplication, or division. Addition and subtraction are handy for times when the number of tests needs to be adjusted on the fly without anything else on the line:

  ## TESTCOUNT + 6

Skipping sections

Entire sections of code can be skipped entirely for the purposed of test counting. Simply add ## START_SKIP_TESTCOUNTING to a line, and add ## STOP_SKIP_TESTCOUNTING when you wish the counting to pick up again.

Group modifiers

If you are working on a large test script, sometimes you may want to limit your current testing to not include some related groups of tests. To do this with test_counting, create global variables name $TEST_name at the top of your script, then assign them either a 1 or a 0 to indicate that the sections are on or off. Then add that name as a comment to each line that invokes it. For example:

  our $TEST_ALPHA = 1;
  our $TEST_DELTA = 0;

  pass("red");
  pass("blue"); ## TEST_ALPHA
  pass("yellow"); ## TEST_DELTA

In the above example, the "yellow" test will not be counted, because it belongs to the TEST_DELTA group, which is off.

Adding START_ and STOP_ before the group name allows you to associate a block of code with a named section: this is usually used in conjunction with an if statement telling those tests not to run. For example:

  if ($TEST_DELTA) { ## START_TEST_DELTA
     cmp($x,$y, "Values are the same");
     ## Time-consuming tests here...
  } ## STOP_TEST_DELTA

Note that lines may contain more than one control comment, such as:

foo(3,42); ## TEST_DELTA TESTCOUNT + 10

Environment groupings

A named group can also be controlled by an environment variable. The format is ## ENV_name, or ## START_ENV_name and ##STOP_ENV_name.

No-op lines

If you put a comment on a line with only a single semi-colon at the start of it, this line will be evaluated right away for any TESTCOUNT effects. For example, to add 24 tests if the environment variable BUCARDO_TEST_RING is set:

  ;## ENV_BUCARDO_TEST_RING       TESTCOUNT+24

Negation

The group and environment modifiers can be negated by using NOTEST and NOENV. When combined with a no-op TESTCOUNT line, this can be an easy way to adjust the tests based on if, for example, an ENV variable is set:

  ; ## NOENV_FOOBAR TESTCOUNT - 10;

In the example above, the total number of tests is reduced by 10 unless the environment variable has been set.

LIMITATIONS

This module is not going to be perfect at test counting every time - a task which would require Artificial Intelligence - but is designed to make your task easier.

For a small and simple test script, use of Test::Dynamic may be overkill.

BUGS

Bugs should be reported to the author.

WEBSITE

The latest information on this module can be found at:

  http://bucardo.org/test_dynamic/

DEVELOPMENT

The latest development version can be checked out via git as:

  git-clone http://bucardo.org/testdynamic.git/

AUTHOR

Greg Sabino Mullane <greg@endpoint.com>

LICENSE AND COPYRIGHT

Copyright 2006-2007 Greg Sabino Mullane <greg@endpoint.com>.

This software is free to use: see the LICENSE file for details.