Add built local::lib
[catagits/Gitalist.git] / local-lib5 / man / man3 / TAP::Harness.3pm
1 .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.3
2 .\"
3 .\" Standard preamble:
4 .\" ========================================================================
5 .de Sh \" Subsection heading
6 .br
7 .if t .Sp
8 .ne 5
9 .PP
10 \fB\\$1\fR
11 .PP
12 ..
13 .de Sp \" Vertical space (when we can't use .PP)
14 .if t .sp .5v
15 .if n .sp
16 ..
17 .de Vb \" Begin verbatim text
18 .ft CW
19 .nf
20 .ne \\$1
21 ..
22 .de Ve \" End verbatim text
23 .ft R
24 .fi
25 ..
26 .\" Set up some character translations and predefined strings.  \*(-- will
27 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
28 .\" double quote, and \*(R" will give a right double quote.  | will give a
29 .\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
30 .\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
31 .\" expand to `' in nroff, nothing in troff, for use with C<>.
32 .tr \(*W-|\(bv\*(Tr
33 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
34 .ie n \{\
35 .    ds -- \(*W-
36 .    ds PI pi
37 .    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
38 .    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
39 .    ds L" ""
40 .    ds R" ""
41 .    ds C` ""
42 .    ds C' ""
43 'br\}
44 .el\{\
45 .    ds -- \|\(em\|
46 .    ds PI \(*p
47 .    ds L" ``
48 .    ds R" ''
49 'br\}
50 .\"
51 .\" If the F register is turned on, we'll generate index entries on stderr for
52 .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
53 .\" entries marked with X<> in POD.  Of course, you'll have to process the
54 .\" output yourself in some meaningful fashion.
55 .if \nF \{\
56 .    de IX
57 .    tm Index:\\$1\t\\n%\t"\\$2"
58 ..
59 .    nr % 0
60 .    rr F
61 .\}
62 .\"
63 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
64 .\" way too many mistakes in technical documents.
65 .hy 0
66 .if n .na
67 .\"
68 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
69 .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
70 .    \" fudge factors for nroff and troff
71 .if n \{\
72 .    ds #H 0
73 .    ds #V .8m
74 .    ds #F .3m
75 .    ds #[ \f1
76 .    ds #] \fP
77 .\}
78 .if t \{\
79 .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
80 .    ds #V .6m
81 .    ds #F 0
82 .    ds #[ \&
83 .    ds #] \&
84 .\}
85 .    \" simple accents for nroff and troff
86 .if n \{\
87 .    ds ' \&
88 .    ds ` \&
89 .    ds ^ \&
90 .    ds , \&
91 .    ds ~ ~
92 .    ds /
93 .\}
94 .if t \{\
95 .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
96 .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
97 .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
98 .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
99 .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
100 .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
101 .\}
102 .    \" troff and (daisy-wheel) nroff accents
103 .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
104 .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
105 .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
106 .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
107 .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
108 .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
109 .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
110 .ds ae a\h'-(\w'a'u*4/10)'e
111 .ds Ae A\h'-(\w'A'u*4/10)'E
112 .    \" corrections for vroff
113 .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
114 .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
115 .    \" for low resolution devices (crt and lpr)
116 .if \n(.H>23 .if \n(.V>19 \
117 \{\
118 .    ds : e
119 .    ds 8 ss
120 .    ds o a
121 .    ds d- d\h'-1'\(ga
122 .    ds D- D\h'-1'\(hy
123 .    ds th \o'bp'
124 .    ds Th \o'LP'
125 .    ds ae ae
126 .    ds Ae AE
127 .\}
128 .rm #[ #] #H #V #F C
129 .\" ========================================================================
130 .\"
131 .IX Title "TAP::Harness 3"
132 .TH TAP::Harness 3 "2009-05-05" "perl v5.8.7" "User Contributed Perl Documentation"
133 .SH "NAME"
134 TAP::Harness \- Run test scripts with statistics
135 .SH "VERSION"
136 .IX Header "VERSION"
137 Version 3.17
138 .SH "DESCRIPTION"
139 .IX Header "DESCRIPTION"
140 This is a simple test harness which allows tests to be run and results
141 automatically aggregated and output to \s-1STDOUT\s0.
142 .SH "SYNOPSIS"
143 .IX Header "SYNOPSIS"
144 .Vb 3
145 \& use TAP::Harness;
146 \& my $harness = TAP::Harness\->new( \e%args );
147 \& $harness\->runtests(@tests);
148 .Ve
149 .SH "METHODS"
150 .IX Header "METHODS"
151 .Sh "Class Methods"
152 .IX Subsection "Class Methods"
153 \fI\f(CI\*(C`new\*(C'\fI\fR
154 .IX Subsection "new"
155 .PP
156 .Vb 5
157 \& my %args = (
158 \&    verbosity => 1,
159 \&    lib     => [ 'lib', 'blib/lib', 'blib/arch' ],
160 \& )
161 \& my $harness = TAP::Harness\->new( \e%args );
162 .Ve
163 .PP
164 The constructor returns a new \f(CW\*(C`TAP::Harness\*(C'\fR object. It accepts an
165 optional hashref whose allowed keys are:
166 .ie n .IP "* ""verbosity""" 4
167 .el .IP "* \f(CWverbosity\fR" 4
168 .IX Item "verbosity"
169 Set the verbosity level:
170 .Sp
171 .Vb 6
172 \&     1   verbose        Print individual test results to STDOUT.
173 \&     0   normal
174 \&    \-1   quiet          Suppress some test output (mostly failures 
175 \&                        while tests are running).
176 \&    \-2   really quiet   Suppress everything but the tests summary.
177 \&    \-3   silent         Suppress everything.
178 .Ve
179 .ie n .IP "* ""timer""" 4
180 .el .IP "* \f(CWtimer\fR" 4
181 .IX Item "timer"
182 Append run time for each test to output. Uses Time::HiRes if
183 available.
184 .ie n .IP "* ""failures""" 4
185 .el .IP "* \f(CWfailures\fR" 4
186 .IX Item "failures"
187 Show test failures (this is a no-op if \f(CW\*(C`verbose\*(C'\fR is selected).
188 .ie n .IP "* ""comments""" 4
189 .el .IP "* \f(CWcomments\fR" 4
190 .IX Item "comments"
191 Show test comments (this is a no-op if \f(CW\*(C`verbose\*(C'\fR is selected).
192 .ie n .IP "* ""show_count""" 4
193 .el .IP "* \f(CWshow_count\fR" 4
194 .IX Item "show_count"
195 Update the running test count during testing.
196 .ie n .IP "* ""normalize""" 4
197 .el .IP "* \f(CWnormalize\fR" 4
198 .IX Item "normalize"
199 Set to a true value to normalize the \s-1TAP\s0 that is emitted in verbose modes.
200 .ie n .IP "* ""lib""" 4
201 .el .IP "* \f(CWlib\fR" 4
202 .IX Item "lib"
203 Accepts a scalar value or array ref of scalar values indicating which
204 paths to allowed libraries should be included if Perl tests are
205 executed. Naturally, this only makes sense in the context of tests
206 written in Perl.
207 .ie n .IP "* ""switches""" 4
208 .el .IP "* \f(CWswitches\fR" 4
209 .IX Item "switches"
210 Accepts a scalar value or array ref of scalar values indicating which
211 switches should be included if Perl tests are executed. Naturally, this
212 only makes sense in the context of tests written in Perl.
213 .ie n .IP "* ""test_args""" 4
214 .el .IP "* \f(CWtest_args\fR" 4
215 .IX Item "test_args"
216 A reference to an \f(CW@INC\fR style array of arguments to be passed to each
217 test program.
218 .ie n .IP "* ""color""" 4
219 .el .IP "* \f(CWcolor\fR" 4
220 .IX Item "color"
221 Attempt to produce color output.
222 .ie n .IP "* ""exec""" 4
223 .el .IP "* \f(CWexec\fR" 4
224 .IX Item "exec"
225 Typically, Perl tests are run through this. However, anything which
226 spits out \s-1TAP\s0 is fine. You can use this argument to specify the name of
227 the program (and optional switches) to run your tests with:
228 .Sp
229 .Vb 1
230 \&  exec => ['/usr/bin/ruby', '\-w']
231 .Ve
232 .Sp
233 You can also pass a subroutine reference in order to determine and
234 return the proper program to run based on a given test script. The
235 subroutine reference should expect the TAP::Harness object itself as the
236 first argument, and the file name as the second argument. It should
237 return an array reference containing the command to be run and including
238 the test file name. It can also simply return \f(CW\*(C`undef\*(C'\fR, in which case
239 TAP::Harness will fall back on executing the test script in Perl:
240 .Sp
241 .Vb 2
242 \&    exec => sub {
243 \&        my ( $harness, $test_file ) = @_;
244 .Ve
245 .Sp
246 .Vb 5
247 \&        # Let Perl tests run.
248 \&        return undef if $test_file =~ /[.]t$/;
249 \&        return [ qw( /usr/bin/ruby \-w ), $test_file ]
250 \&          if $test_file =~ /[.]rb$/;
251 \&      }
252 .Ve
253 .Sp
254 If the subroutine returns a scalar with a newline or a filehandle, it
255 will be interpreted as raw \s-1TAP\s0 or as a \s-1TAP\s0 stream, respectively.
256 .ie n .IP "* ""merge""" 4
257 .el .IP "* \f(CWmerge\fR" 4
258 .IX Item "merge"
259 If \f(CW\*(C`merge\*(C'\fR is true the harness will create parsers that merge \s-1STDOUT\s0
260 and \s-1STDERR\s0 together for any processes they start.
261 .ie n .IP "* ""aggregator_class""" 4
262 .el .IP "* \f(CWaggregator_class\fR" 4
263 .IX Item "aggregator_class"
264 The name of the class to use to aggregate test results. The default is
265 TAP::Parser::Aggregator.
266 .ie n .IP "* ""formatter_class""" 4
267 .el .IP "* \f(CWformatter_class\fR" 4
268 .IX Item "formatter_class"
269 The name of the class to use to format output. The default is
270 TAP::Formatter::Console, or TAP::Formatter::File if the output
271 isn't a \s-1TTY\s0.
272 .ie n .IP "* ""multiplexer_class""" 4
273 .el .IP "* \f(CWmultiplexer_class\fR" 4
274 .IX Item "multiplexer_class"
275 The name of the class to use to multiplex tests during parallel testing.
276 The default is TAP::Parser::Multiplexer.
277 .ie n .IP "* ""parser_class""" 4
278 .el .IP "* \f(CWparser_class\fR" 4
279 .IX Item "parser_class"
280 The name of the class to use to parse \s-1TAP\s0. The default is
281 TAP::Parser.
282 .ie n .IP "* ""scheduler_class""" 4
283 .el .IP "* \f(CWscheduler_class\fR" 4
284 .IX Item "scheduler_class"
285 The name of the class to use to schedule test execution. The default is
286 TAP::Parser::Scheduler.
287 .ie n .IP "* ""formatter""" 4
288 .el .IP "* \f(CWformatter\fR" 4
289 .IX Item "formatter"
290 If set \f(CW\*(C`formatter\*(C'\fR must be an object that is capable of formatting the
291 \&\s-1TAP\s0 output. See TAP::Formatter::Console for an example.
292 .ie n .IP "* ""errors""" 4
293 .el .IP "* \f(CWerrors\fR" 4
294 .IX Item "errors"
295 If parse errors are found in the \s-1TAP\s0 output, a note of this will be
296 made in the summary report. To see all of the parse errors, set this
297 argument to true:
298 .Sp
299 .Vb 1
300 \&  errors => 1
301 .Ve
302 .ie n .IP "* ""directives""" 4
303 .el .IP "* \f(CWdirectives\fR" 4
304 .IX Item "directives"
305 If set to a true value, only test results with directives will be
306 displayed. This overrides other settings such as \f(CW\*(C`verbose\*(C'\fR or
307 \&\f(CW\*(C`failures\*(C'\fR.
308 .ie n .IP "* ""ignore_exit""" 4
309 .el .IP "* \f(CWignore_exit\fR" 4
310 .IX Item "ignore_exit"
311 If set to a true value instruct \f(CW\*(C`TAP::Parser\*(C'\fR to ignore exit and wait
312 status from test scripts.
313 .ie n .IP "* ""jobs""" 4
314 .el .IP "* \f(CWjobs\fR" 4
315 .IX Item "jobs"
316 The maximum number of parallel tests to run at any time.  Which tests
317 can be run in parallel is controlled by \f(CW\*(C`rules\*(C'\fR.  The default is to
318 run only one test at a time.
319 .ie n .IP "* ""rules""" 4
320 .el .IP "* \f(CWrules\fR" 4
321 .IX Item "rules"
322 A reference to a hash of rules that control which tests may be
323 executed in parallel. This is an experimental feature and the
324 interface may change.
325 .Sp
326 .Vb 10
327 \&    $harness\->rules(
328 \&        {   par => [
329 \&                { seq => '../ext/DB_File/t/*' },
330 \&                { seq => '../ext/IO_Compress_Zlib/t/*' },
331 \&                { seq => '../lib/CPANPLUS/*' },
332 \&                { seq => '../lib/ExtUtils/t/*' },
333 \&                '*'
334 \&            ]
335 \&        }
336 \&    );
337 .Ve
338 .ie n .IP "* ""stdout""" 4
339 .el .IP "* \f(CWstdout\fR" 4
340 .IX Item "stdout"
341 A filehandle for catching standard output.
342 .PP
343 Any keys for which the value is \f(CW\*(C`undef\*(C'\fR will be ignored.
344 .Sh "Instance Methods"
345 .IX Subsection "Instance Methods"
346 \fI\f(CI\*(C`runtests\*(C'\fI\fR
347 .IX Subsection "runtests"
348 .PP
349 .Vb 1
350 \&    $harness\->runtests(@tests);
351 .Ve
352 .PP
353 Accepts and array of \f(CW@tests\fR to be run. This should generally be the
354 names of test files, but this is not required. Each element in \f(CW@tests\fR
355 will be passed to \f(CW\*(C`TAP::Parser::new()\*(C'\fR as a \f(CW\*(C`source\*(C'\fR. See
356 TAP::Parser for more information.
357 .PP
358 It is possible to provide aliases that will be displayed in place of the
359 test name by supplying the test as a reference to an array containing
360 \&\f(CW\*(C`[ $test, $alias ]\*(C'\fR:
361 .PP
362 .Vb 2
363 \&    $harness\->runtests( [ 't/foo.t', 'Foo Once' ],
364 \&                        [ 't/foo.t', 'Foo Twice' ] );
365 .Ve
366 .PP
367 Normally it is an error to attempt to run the same test twice. Aliases
368 allow you to overcome this limitation by giving each run of the test a
369 unique name.
370 .PP
371 Tests will be run in the order found.
372 .PP
373 If the environment variable \f(CW\*(C`PERL_TEST_HARNESS_DUMP_TAP\*(C'\fR is defined it
374 should name a directory into which a copy of the raw \s-1TAP\s0 for each test
375 will be written. \s-1TAP\s0 is written to files named for each test.
376 Subdirectories will be created as needed.
377 .PP
378 Returns a TAP::Parser::Aggregator containing the test results.
379 .PP
380 \fI\f(CI\*(C`summary\*(C'\fI\fR
381 .IX Subsection "summary"
382 .PP
383 Output the summary for a TAP::Parser::Aggregator.
384 .PP
385 \fI\f(CI\*(C`aggregate_tests\*(C'\fI\fR
386 .IX Subsection "aggregate_tests"
387 .PP
388 .Vb 1
389 \&  $harness\->aggregate_tests( $aggregate, @tests );
390 .Ve
391 .PP
392 Run the named tests and display a summary of result. Tests will be run
393 in the order found. 
394 .PP
395 Test results will be added to the supplied TAP::Parser::Aggregator.
396 \&\f(CW\*(C`aggregate_tests\*(C'\fR may be called multiple times to run several sets of
397 tests. Multiple \f(CW\*(C`Test::Harness\*(C'\fR instances may be used to pass results
398 to a single aggregator so that different parts of a complex test suite
399 may be run using different \f(CW\*(C`TAP::Harness\*(C'\fR settings. This is useful, for
400 example, in the case where some tests should run in parallel but others
401 are unsuitable for parallel execution.
402 .PP
403 .Vb 8
404 \&    my $formatter   = TAP::Formatter::Console\->new;
405 \&    my $ser_harness = TAP::Harness\->new( { formatter => $formatter } );
406 \&    my $par_harness = TAP::Harness\->new(
407 \&        {   formatter => $formatter,
408 \&            jobs      => 9
409 \&        }
410 \&    );
411 \&    my $aggregator = TAP::Parser::Aggregator\->new;
412 .Ve
413 .PP
414 .Vb 5
415 \&    $aggregator\->start();
416 \&    $ser_harness\->aggregate_tests( $aggregator, @ser_tests );
417 \&    $par_harness\->aggregate_tests( $aggregator, @par_tests );
418 \&    $aggregator\->stop();
419 \&    $formatter\->summary($aggregator);
420 .Ve
421 .PP
422 Note that for simpler testing requirements it will often be possible to
423 replace the above code with a single call to \f(CW\*(C`runtests\*(C'\fR.
424 .PP
425 Each elements of the \f(CW@tests\fR array is either
426 .IP "* the file name of a test script to run" 4
427 .IX Item "the file name of a test script to run"
428 .PD 0
429 .IP "* a reference to a [ file name, display name ] array" 4
430 .IX Item "a reference to a [ file name, display name ] array"
431 .PD
432 .PP
433 When you supply a separate display name it becomes possible to run a
434 test more than once; the display name is effectively the alias by which
435 the test is known inside the harness. The harness doesn't care if it
436 runs the same script more than once when each invocation uses a
437 different name.
438 .PP
439 \fI\f(CI\*(C`make_scheduler\*(C'\fI\fR
440 .IX Subsection "make_scheduler"
441 .PP
442 Called by the harness when it needs to create a
443 TAP::Parser::Scheduler. Override in a subclass to provide an
444 alternative scheduler. \f(CW\*(C`make_scheduler\*(C'\fR is passed the list of tests
445 that was passed to \f(CW\*(C`aggregate_tests\*(C'\fR.
446 .PP
447 \fI\f(CI\*(C`jobs\*(C'\fI\fR
448 .IX Subsection "jobs"
449 .PP
450 Gets or sets the number of concurrent test runs the harness is
451 handling.  By default, this value is 1 \*(-- for parallel testing, this
452 should be set higher.
453 .SH "SUBCLASSING"
454 .IX Header "SUBCLASSING"
455 \&\f(CW\*(C`TAP::Harness\*(C'\fR is designed to be (mostly) easy to subclass. If you
456 don't like how a particular feature functions, just override the
457 desired methods.
458 .Sh "Methods"
459 .IX Subsection "Methods"
460 \&\s-1TODO:\s0 This is out of date
461 .PP
462 The following methods are ones you may wish to override if you want to
463 subclass \f(CW\*(C`TAP::Harness\*(C'\fR.
464 .PP
465 \fI\f(CI\*(C`summary\*(C'\fI\fR
466 .IX Subsection "summary"
467 .PP
468 .Vb 1
469 \&  $harness\->summary( \e%args );
470 .Ve
471 .PP
472 \&\f(CW\*(C`summary\*(C'\fR prints the summary report after all tests are run. The
473 argument is a hashref with the following keys:
474 .ie n .IP "* ""start""" 4
475 .el .IP "* \f(CWstart\fR" 4
476 .IX Item "start"
477 This is created with \f(CW\*(C`Benchmark\->new\*(C'\fR and it the time the tests
478 started. You can print a useful summary time, if desired, with:
479 .Sp
480 .Vb 2
481 \&    $self\->output(
482 \&        timestr( timediff( Benchmark\->new, $start_time ), 'nop' ) );
483 .Ve
484 .ie n .IP "* ""tests""" 4
485 .el .IP "* \f(CWtests\fR" 4
486 .IX Item "tests"
487 This is an array reference of all test names. To get the TAP::Parser
488 object for individual tests:
489 .Sp
490 .Vb 2
491 \& my $aggregate = $args\->{aggregate};
492 \& my $tests     = $args\->{tests};
493 .Ve
494 .Sp
495 .Vb 4
496 \& for my $name ( @$tests ) {
497 \&     my ($parser) = $aggregate\->parsers($test);
498 \&     ... do something with $parser
499 \& }
500 .Ve
501 .Sp
502 This is a bit clunky and will be cleaned up in a later release.
503 .PP
504 \fI\f(CI\*(C`make_parser\*(C'\fI\fR
505 .IX Subsection "make_parser"
506 .PP
507 Make a new parser and display formatter session. Typically used and/or
508 overridden in subclasses.
509 .PP
510 .Vb 1
511 \&    my ( $parser, $session ) = $harness\->make_parser;
512 .Ve
513 .PP
514 \fI\f(CI\*(C`finish_parser\*(C'\fI\fR
515 .IX Subsection "finish_parser"
516 .PP
517 Terminate use of a parser. Typically used and/or overridden in
518 subclasses. The parser isn't destroyed as a result of this.
519 .SH "REPLACING"
520 .IX Header "REPLACING"
521 If you like the \f(CW\*(C`prove\*(C'\fR utility and TAP::Parser but you want your
522 own harness, all you need to do is write one and provide \f(CW\*(C`new\*(C'\fR and
523 \&\f(CW\*(C`runtests\*(C'\fR methods. Then you can use the \f(CW\*(C`prove\*(C'\fR utility like so:
524 .PP
525 .Vb 1
526 \& prove \-\-harness My::Test::Harness
527 .Ve
528 .PP
529 Note that while \f(CW\*(C`prove\*(C'\fR accepts a list of tests (or things to be
530 tested), \f(CW\*(C`new\*(C'\fR has a fairly rich set of arguments. You'll probably want
531 to read over this code carefully to see how all of them are being used.
532 .SH "SEE ALSO"
533 .IX Header "SEE ALSO"
534 Test::Harness