File Coverage

blib/lib/Test/Steering.pm
Criterion Covered Total %
statement 43 44 97.7
branch 3 6 50.0
condition 6 9 66.6
subroutine 13 13 100.0
pod n/a
total 65 72 90.2


line stmt bran cond sub pod time code
1             package Test::Steering;
2              
3 3     3   47355 use warnings;
  3         7  
  3         90  
4 3     3   18 use strict;
  3         8  
  3         109  
5 3     3   15 use Exporter;
  3         11  
  3         127  
6 3     3   14 use Carp;
  3         6  
  3         475  
7              
8             =head1 NAME
9              
10             Test::Steering - Execute test scripts conditionally
11              
12             =head1 VERSION
13              
14             This document describes Test::Steering version 0.02
15              
16             =cut
17              
18             our $VERSION = '0.02';
19             our @ISA = qw(Exporter);
20             our @EXPORT;
21              
22             BEGIN {
23 3     3   9 @EXPORT = qw(include_tests end_plan tests_run);
24 3         5 my $WHEEL;
25 3         7 for my $method ( @EXPORT ) {
26 3     3   14 no strict 'refs';
  3         6  
  3         243  
27 9         1046 *{ __PACKAGE__ . '::' . $method } = sub {
28 7   66 7   2092 return ( $WHEEL ||= _make_wheel() )->$method( @_ );
29 9         29 };
30             }
31             }
32              
33             =head1 SYNOPSIS
34              
35             use Test::Steering;
36              
37             include_tests( 'xt/vms/*.t' ) if $^O eq 'VMS';
38             include_tests( 'xt/windows/*.t' ) if $^O =~ 'MSWin32';
39              
40             =head1 DESCRIPTION
41              
42             Often it is useful to have more control over which tests are executed
43             - and how. You can exercise some degree of control by SKIPping
44             unwanted tests but that can be inefficient and cumbersome for large
45             test suites.
46              
47             C runs test scripts and filters their output into a
48             single, syntactically correct TAP stream. In this way a single test
49             script can be responsible for running multiple other tests.
50              
51             The parameters for the L used run the subtests can also
52             be controlled making it possible to, for example, run certain tests
53             in parallel.
54              
55             At some point in the future it is likely that TAP syntax will be
56             extended to support hierarchical results. See
57              
58             http://testanything.org/wiki/index.php/Test_Groups
59             http://testanything.org/wiki/index.php/Test_Blocks
60              
61             for proposed schemes.
62              
63             When hierarchical TAP is implemented this module will be upgraded to
64             support it.
65              
66             =head1 INTERFACE
67              
68             =head2 C<< include_tests >>
69              
70             Run one or more tests. Wildcards will be expanded.
71              
72             include_tests( 'xt/vms/*.t' ) if $^O eq 'VMS';
73             include_tests( 'xt/windows/*.t' ) if $^O =~ 'MSWin32';
74              
75             Behind the scenes a new L will be created and used to run
76             the individual test scripts. The output test results are concatenated,
77             tests renumbered and then sent to STDOUT. The net effect of which is
78             that multiple tests are able to masquerade as a single test.
79              
80             If there are any problems running the tests (TAP syntax errors, non-zero
81             exit status) those will be turned into additional test failures.
82              
83             In addition to test names you may pass hash references which will be passed
84             to C<< TAP::Harness->new >>.
85              
86             # Run tests in parallel
87             include_tests( { jobs => 9 }, 'xt/parallel/*/t' );
88              
89             Multiple options hashes may be provided; they will be concatenated.
90              
91             # Run tests in parallel, enable warnings
92             include_tests( { jobs => 9 },
93             'xt/parallel/*/t', { switches => ['-w'] } );
94              
95             =head2 C<< end_plan >>
96              
97             Output the trailing plan. Normally there is no need to call C
98             directly: it is called on exit.
99              
100             =head2 C<< tests_run >>
101              
102             Get a list of tests that have been run.
103              
104             my @tests = tests_run();
105              
106             =head1 OPTIONS
107              
108             A number of options may be passed.
109              
110             use Test::Steering wheel => 'My::Wheel';
111              
112             =over
113              
114             =item C
115              
116             Add the name of the current test as a prefix to each result's
117             description.
118              
119             =item C
120              
121             Output a diagnostic naming each new subtest
122              
123             =item C
124              
125             A hash containing default options for C.
126              
127             =item C
128              
129             The name of the support class that will be used. Defaults to
130             C. Use this option to use a custom subclass.
131              
132             =back
133              
134             =cut
135              
136             sub _load {
137 6     6   10 my $class = shift;
138 2 50 66 2   1140 unless ( $INC{$class} || eval "use $class; 1" ) {
  2     2   6  
  2         43  
  2         18  
  2         5  
  2         36  
  6         350  
139 0         0 croak "Can't load $class: $@";
140             }
141 6         50 return $class;
142             }
143              
144             {
145             my $wheel_class = 'Test::Steering::Wheel';
146             my %options;
147              
148             sub import {
149 3     3   35 my $class = shift;
150 3 50       18 croak "Must supply an even number of arguments" if @_ % 1;
151 3         8 my %opts = @_;
152              
153 3   66     17 $wheel_class = delete $opts{wheel} || $wheel_class;
154              
155 3         8 my %valid = map { $_ => 1 } _load( $wheel_class )->option_names;
  8         28  
156 3         15 my @bad = grep { !$valid{$_} } keys %opts;
  1         4  
157 3 50       14 croak "Unknown option(s): ", join ', ', sort @bad if @bad;
158              
159 3         10 %options = %opts;
160              
161             # We don't pass any args downwards
162 3         3838 $class->export_to_level( 1 );
163             }
164              
165             sub _make_wheel {
166 3     3   13 return _load( $wheel_class )->new( %options );
167             }
168             }
169              
170             END {
171 3     3   2611 end_plan();
172             }
173              
174             1;
175             __END__