File Coverage

blib/lib/Test/Unit/TestSuite.pm
Criterion Covered Total %
statement 94 121 77.6
branch 20 30 66.6
condition 11 17 64.7
subroutine 16 22 72.7
pod 6 15 40.0
total 147 205 71.7


line stmt bran cond sub pod time code
1             package Test::Unit::TestSuite;
2 2     2   11 use strict;
  2         3  
  2         77  
3              
4             =head1 NAME
5              
6             Test::Unit::TestSuite - unit testing framework base class
7              
8             =cut
9              
10 2     2   10 use base 'Test::Unit::Test';
  2         4  
  2         1034  
11              
12 2     2   17 use Carp;
  2         5  
  2         140  
13              
14 2     2   14 use Test::Unit::Debug qw(debug);
  2         5  
  2         100  
15 2     2   3261 use Test::Unit::TestCase;
  2         7  
  2         61  
16 2     2   13 use Test::Unit::Loader;
  2         2  
  2         46  
17 2     2   1832 use Test::Unit::Warning;
  2         8  
  2         3145  
18              
19             =head1 SYNOPSIS
20              
21             package MySuite;
22              
23             use base qw(Test::Unit::TestSuite);
24              
25             sub name { 'My very own test suite' }
26             sub include_tests { qw(MySuite1 MySuite2 MyTestCase1 ...) }
27              
28             This is the easiest way of building suites; there are many more. Read on ...
29              
30             =head1 DESCRIPTION
31              
32             This class provides the functionality for building test suites in
33             several different ways.
34              
35             Any module can be a test suite runnable by the framework if it
36             provides a C method which returns a C
37             object, e.g.
38              
39             use Test::Unit::TestSuite;
40              
41             # more code here ...
42              
43             sub suite {
44             my $class = shift;
45              
46             # Create an empty suite.
47             my $suite = Test::Unit::TestSuite->empty_new("A Test Suite");
48             # Add some tests to it via $suite->add_test() here
49              
50             return $suite;
51             }
52              
53             This is useful if you want your test suite to be contained in the module
54             it tests, for example.
55              
56             Alternatively, you can have "standalone" test suites, which inherit directly
57             from C, e.g.:
58              
59             package MySuite;
60              
61             use base qw(Test::Unit::TestSuite);
62              
63             sub new {
64             my $class = shift;
65             my $self = $class->SUPER::empty_new();
66             # Build your suite here
67             return $self;
68             }
69              
70             sub name { 'My very own test suite' }
71              
72             or if your C is going to do nothing more interesting than add
73             tests from other suites and testcases via C, you can use the
74             C method as shorthand:
75              
76             package MySuite;
77              
78             use base qw(Test::Unit::TestSuite);
79              
80             sub name { 'My very own test suite' }
81             sub include_tests { qw(MySuite1 MySuite2 MyTestCase1 ...) }
82              
83             This is the easiest way of building suites.
84              
85             =head1 CONSTRUCTORS
86              
87             =head2 empty_new ([NAME])
88              
89             my $suite = Test::Unit::TestSuite->empty_new('my suite name');
90              
91             Creates a fresh suite with no tests.
92              
93             =cut
94              
95             sub empty_new {
96 30     30 1 100 my $this = shift;
97 30   33     146 my $classname = ref $this || $this;
98 30   100     106 my $name = shift || '';
99            
100 30         122 my $self = {
101             _Tests => [],
102             _Name => $name,
103             };
104 30         77 bless $self, $classname;
105            
106 30         125 debug(ref($self), "::empty_new($name) called\n");
107 30         80 return $self;
108             }
109              
110             =head2 new ([ CLASSNAME | TEST ])
111              
112             If a test suite is provided as the argument, it merely returns that
113             suite. If a test case is provided, it extracts all test case methods
114             from the test case (see L) into a new
115             test suite.
116              
117             If the class this method is being run in has an C method
118             which returns an array of class names, it will also automatically add
119             the tests from those classes into the newly constructed suite object.
120              
121             =cut
122              
123             sub new {
124 24     24 1 1189 my $class = shift;
125 24   100     71 my $classname = shift || ''; # Avoid a warning
126 24         110 debug("$class\::new($classname) called\n");
127              
128 24         91 my $self = $class->empty_new();
129              
130 24 100       68 if ($classname) {
131 22         72 Test::Unit::Loader::compile_class($classname);
132 22 100       64 if (eval { $classname->isa('Test::Unit::TestCase') }) {
  22 50       175  
133 21         100 $self->{_Name} = "suite extracted from $classname";
134 21         91 my @testcases = Test::Unit::Loader::extract_testcases($classname);
135 21         53 foreach my $testcase (@testcases) {
136 68         165 $self->add_test($testcase);
137             }
138             }
139 1         12 elsif (eval { $classname->can('suite') }) {
140 0         0 return $classname->suite();
141             }
142             else {
143 1         3 my $error = "Class $classname was not a test case or test suite.\n";
144             #$self->add_warning($error);
145 1         9 die $error;
146             }
147             }
148              
149 23 100       143 if ($self->can('include_tests')) {
150 2         11 foreach my $test ($self->include_tests()) {
151 2         17 $self->add_test($test);
152             }
153             }
154              
155 23         118 return $self;
156             }
157              
158             =head1 METHODS
159              
160             =cut
161              
162             sub suite {
163 1     1 0 2 my $class = shift;
164 1 50       4 croak "suite() is not an instance method" if ref $class;
165 1         6 $class->new(@_);
166             }
167              
168             =head2 name()
169              
170             Returns the suite's human-readable name.
171              
172             =cut
173              
174             sub name {
175 19     19 1 29 my $self = shift;
176 19 50       39 croak "Override name() in subclass to set name\n" if @_;
177 19         129 return $self->{_Name};
178             }
179              
180             =head2 names()
181              
182             Returns an arrayref of the names of all tests in the suite.
183              
184             =cut
185              
186             sub names {
187 0     0 1 0 my $self = shift;
188 0         0 my @test_list = @{$self->tests};
  0         0  
189 0 0       0 return [ map {$_->name} @test_list ] if @test_list;
  0         0  
190             }
191              
192             =head2 list (SHOW_TESTCASES)
193              
194             Produces a human-readable indented lists of the suite and the subsuites
195             it contains. If the first parameter is true, also lists any testcases
196             contained in the suite and its subsuites.
197              
198             =cut
199              
200             sub list {
201 0     0 1 0 my $self = shift;
202 0         0 my $show_testcases = shift;
203 0   0     0 my $first = ($self->name() || 'anonymous Test::Unit::TestSuite');
204 0 0       0 $first .= " - " . ref($self) unless ref($self) eq __PACKAGE__;
205 0         0 $first .= "\n";
206 0         0 my @lines = ( $first );
207 0         0 foreach my $test (@{ $self->tests() }) {
  0         0  
208 0         0 push @lines, map " $_", @{ $test->list($show_testcases) };
  0         0  
209             }
210 0         0 return \@lines;
211             }
212              
213             =head2 add_test (TEST_CLASSNAME | TEST_OBJECT)
214              
215             You can add a test object to a suite with this method, by passing
216             either its classname, or the object itself as the argument.
217              
218             Of course, there are many ways of getting the object too ...
219              
220             # Get and add an existing suite.
221             $suite->add_test('MySuite1');
222              
223             # This is exactly equivalent:
224             $suite->add_test(Test::Unit::TestSuite->new('MySuite1'));
225              
226             # So is this, provided MySuite1 inherits from Test::Unit::TestSuite.
227             use MySuite1;
228             $suite->add_test(MySuite1->new());
229              
230             # Extract yet another suite by way of suite() method and add it to
231             # $suite.
232             use MySuite2;
233             $suite->add_test(MySuite2->suite());
234            
235             # Extract test case methods from MyModule::TestCase into a
236             # new suite and add it to $suite.
237             $suite->add_test(Test::Unit::TestSuite->new('MyModule::TestCase'));
238              
239             =cut
240              
241             sub add_test {
242 130     130 1 563 my $self = shift;
243 130         157 my ($test) = @_;
244 130         1340 debug('+ ', ref($self), "::add_test($test) called\n");
245 130 100       344 $test = Test::Unit::Loader::load_test($test) unless ref $test;
246             croak "`$test' could not be interpreted as a Test::Unit::Test object"
247 130 50       163 unless eval { $test->isa('Test::Unit::Test') };
  130         1501  
248 130         180 push @{$self->tests}, $test;
  130         423  
249             }
250              
251             sub count_test_cases {
252 12     12 0 19 my $self = shift;
253 12         15 my $count;
254 12         18 $count += $_->count_test_cases for @{$self->tests};
  12         27  
255 12         52 return $count;
256             }
257              
258             sub run {
259 23     23 0 88 my $self = shift;
260 23         41 my ($result, $runner) = @_;
261              
262 23   100     205 debug("$self\::run($result, ", $runner || 'undef', ") called\n");
263              
264 23   33     76 $result ||= create_result();
265 23         89 $result->tell_listeners(start_suite => $self);
266              
267 23         124 $self->add_warning("No tests found in " . $self->name())
268 23 50       46 unless @{ $self->tests() };
269              
270 23         33 for my $t (@{$self->tests()}) {
  23         53  
271 121 100 100     758 if ($runner && $self->filter_test($runner, $t)) {
272 6         17 debug(sprintf "+ skipping '%s'\n", $t->name());
273 6         12 next;
274             }
275 114         451 debug(sprintf "+ didn't skip '%s'\n", $t->name());
276            
277 114 50       442 last if $result->should_stop();
278 114         653 $t->run($result, $runner);
279             }
280              
281 22         79 $result->tell_listeners(end_suite => $self);
282              
283 22         63 return $result;
284             }
285            
286             sub filter_test {
287 112     112 0 159 my $self = shift;
288 112         169 my ($runner, $test) = @_;
289              
290 112         726 debug(sprintf "checking whether to filter '%s'\n", $test->name);
291              
292 112         616 my @filter_tokens = $runner->filter();
293              
294 112         270 foreach my $token (@filter_tokens) {
295 16         68 my $filtered = $test->filter_method($token);
296 15 100       103 debug(" - by token $token? ", $filtered ? 'yes' : 'no', "\n");
297 15 100       61 return 1 if $filtered;
298             }
299              
300 105         451 return 0;
301             }
302              
303             sub test_at {
304 0     0 0 0 my $self = shift;
305 0         0 my ($index) = @_;
306 0         0 return $self->tests()->[$index];
307             }
308              
309             sub test_count {
310 0     0 0 0 my $self = shift;
311 0         0 return scalar @{$self->tests()};
  0         0  
312             }
313              
314             sub tests {
315 188     188 0 1422 my $self = shift;
316 188         947 return $self->{_Tests};
317             }
318              
319             sub to_string {
320 0     0 0   my $self = shift;
321 0           return $self->name();
322             }
323              
324             sub add_warning {
325 0     0 0   my $self = shift;
326 0           $self->add_test(Test::Unit::Warning->new(join '', @_));
327             }
328              
329             1;
330             __END__