Upgrade to Test::Harness 2.46
[p5sagit/p5-mst-13.2.git] / lib / Test / Harness.pm
CommitLineData
d667a7e6 1# -*- Mode: cperl; cperl-indent-level: 4 -*-
b82fa0b7 2
a0d0e21e 3package Test::Harness;
4
3c87ea76 5require 5.00405;
13287dd5 6use Test::Harness::Straps;
7use Test::Harness::Assert;
a0d0e21e 8use Exporter;
9use Benchmark;
4633a7c4 10use Config;
760ac839 11use strict;
12
e4fc8a1e 13use vars qw(
14 $VERSION
15 @ISA @EXPORT @EXPORT_OK
16 $Verbose $Switches $Debug
17 $verbose $switches $debug
e4fc8a1e 18 $Curtest
19 $Columns
20 $ML $Last_ML_Print
21 $Strap
22);
23
24=head1 NAME
25
26Test::Harness - Run Perl standard test scripts with statistics
27
28=head1 VERSION
29
3c87ea76 30Version 2.46
e4fc8a1e 31
32=cut
33
3c87ea76 34$VERSION = "2.46";
4633a7c4 35
9c5c68c8 36# Backwards compatibility for exportable variable names.
5c0604c3 37*verbose = *Verbose;
38*switches = *Switches;
e4fc8a1e 39*debug = *Debug;
9c5c68c8 40
f19ae7a7 41$ENV{HARNESS_ACTIVE} = 1;
42
13287dd5 43END {
44 # For VMS.
45 delete $ENV{HARNESS_ACTIVE};
46}
47
9b0ceca9 48# Some experimental versions of OS/2 build have broken $?
9c5c68c8 49my $Ignore_Exitcode = $ENV{HARNESS_IGNORE_EXITCODE};
50
51my $Files_In_Dir = $ENV{HARNESS_FILELEAK_IN_DIR};
9b0ceca9 52
d5d4ec93 53$Strap = Test::Harness::Straps->new;
17a79f5b 54
3c87ea76 55sub strap { return $Strap };
56
9c5c68c8 57@ISA = ('Exporter');
58@EXPORT = qw(&runtests);
59@EXPORT_OK = qw($verbose $switches);
4633a7c4 60
356733da 61$Verbose = $ENV{HARNESS_VERBOSE} || 0;
e4fc8a1e 62$Debug = $ENV{HARNESS_DEBUG} || 0;
9c5c68c8 63$Switches = "-w";
64$Columns = $ENV{HARNESS_COLUMNS} || $ENV{COLUMNS} || 80;
b82fa0b7 65$Columns--; # Some shells have trouble with a full line of text.
66
b82fa0b7 67=head1 SYNOPSIS
68
69 use Test::Harness;
70
71 runtests(@test_files);
72
73=head1 DESCRIPTION
a0d0e21e 74
3c87ea76 75B<STOP!> If all you want to do is write a test script, consider
76using Test::Simple. Test::Harness is the module that reads the
77output from Test::Simple, Test::More and other modules based on
78Test::Builder. You don't need to know about Test::Harness to use
79those modules.
b82fa0b7 80
3c87ea76 81Test::Harness runs tests and expects output from the test in a
82certain format. That format is called TAP, the Test Anything
83Protocol. It is defined in L<Test::Harness::TAP>.
b82fa0b7 84
3c87ea76 85C<Test::Harness::runtests(@tests)> runs all the testscripts named
86as arguments and checks standard output for the expected strings
87in TAP format.
b82fa0b7 88
3c87ea76 89The F<prove> utility is a thin wrapper around Test::Harness.
b82fa0b7 90
13287dd5 91=head2 Taint mode
92
e4fc8a1e 93Test::Harness will honor the C<-T> or C<-t> in the #! line on your
94test files. So if you begin a test with:
13287dd5 95
96 #!perl -T
97
98the test will be run with taint mode on.
99
13287dd5 100=head2 Configuration variables.
101
102These variables can be used to configure the behavior of
103Test::Harness. They are exported on request.
104
105=over 4
106
3c87ea76 107=item C<$Test::Harness::Verbose>
13287dd5 108
3c87ea76 109The package variable C<$Test::Harness::Verbose> is exportable and can be
e4fc8a1e 110used to let C<runtests()> display the standard output of the script
111without altering the behavior otherwise. The F<prove> utility's C<-v>
112flag will set this.
13287dd5 113
3c87ea76 114=item C<$Test::Harness::switches>
13287dd5 115
3c87ea76 116The package variable C<$Test::Harness::switches> is exportable and can be
13287dd5 117used to set perl command line options used for running the test
e4fc8a1e 118script(s). The default value is C<-w>. It overrides C<HARNESS_SWITCHES>.
13287dd5 119
120=back
121
122
b82fa0b7 123=head2 Failure
124
3c87ea76 125When tests fail, analyze the summary report:
b82fa0b7 126
2fe373ce 127 t/base..............ok
128 t/nonumbers.........ok
129 t/ok................ok
130 t/test-harness......ok
131 t/waterloo..........dubious
b82fa0b7 132 Test returned status 3 (wstat 768, 0x300)
133 DIED. FAILED tests 1, 3, 5, 7, 9, 11, 13, 15, 17, 19
134 Failed 10/20 tests, 50.00% okay
135 Failed Test Stat Wstat Total Fail Failed List of Failed
136 -----------------------------------------------------------------------
137 t/waterloo.t 3 768 20 10 50.00% 1 3 5 7 9 11 13 15 17 19
138 Failed 1/5 test scripts, 80.00% okay. 10/44 subtests failed, 77.27% okay.
139
3c87ea76 140Everything passed but F<t/waterloo.t>. It failed 10 of 20 tests and
b82fa0b7 141exited with non-zero status indicating something dubious happened.
142
143The columns in the summary report mean:
144
145=over 4
146
147=item B<Failed Test>
148
149The test file which failed.
150
151=item B<Stat>
152
153If the test exited with non-zero, this is its exit status.
154
155=item B<Wstat>
156
e4fc8a1e 157The wait status of the test.
b82fa0b7 158
159=item B<Total>
160
161Total number of tests expected to run.
162
163=item B<Fail>
164
165Number which failed, either from "not ok" or because they never ran.
166
167=item B<Failed>
168
169Percentage of the total tests which failed.
170
171=item B<List of Failed>
172
173A list of the tests which failed. Successive failures may be
174abbreviated (ie. 15-20 to indicate that tests 15, 16, 17, 18, 19 and
17520 failed).
176
177=back
178
179
180=head2 Functions
181
182Test::Harness currently only has one function, here it is.
183
184=over 4
185
186=item B<runtests>
187
188 my $allok = runtests(@test_files);
189
3c87ea76 190This runs all the given I<@test_files> and divines whether they passed
b82fa0b7 191or failed based on their output to STDOUT (details above). It prints
192out each individual test which failed along with a summary report and
193a how long it all took.
194
3c87ea76 195It returns true if everything was ok. Otherwise it will C<die()> with
d5d4ec93 196one of the messages in the DIAGNOSTICS section.
b82fa0b7 197
b82fa0b7 198=cut
17a79f5b 199
a0d0e21e 200sub runtests {
201 my(@tests) = @_;
9c5c68c8 202
b82fa0b7 203 local ($\, $,);
204
205 my($tot, $failedtests) = _run_all_tests(@tests);
9c5c68c8 206 _show_results($tot, $failedtests);
207
2fe373ce 208 my $ok = _all_ok($tot);
b82fa0b7 209
13287dd5 210 assert(($ok xor keys %$failedtests),
211 q{ok status jives with $failedtests});
b82fa0b7 212
213 return $ok;
214}
215
216=begin _private
217
2fe373ce 218=item B<_all_ok>
219
220 my $ok = _all_ok(\%tot);
221
222Tells you if this test run is overall successful or not.
223
224=cut
225
226sub _all_ok {
227 my($tot) = shift;
228
229 return $tot->{bad} == 0 && ($tot->{max} || $tot->{skipped}) ? 1 : 0;
230}
231
b82fa0b7 232=item B<_globdir>
233
234 my @files = _globdir $dir;
235
236Returns all the files in a directory. This is shorthand for backwards
3c87ea76 237compatibility on systems where C<glob()> doesn't work right.
b82fa0b7 238
239=cut
240
241sub _globdir {
242 opendir DIRH, shift;
243 my @f = readdir DIRH;
244 closedir DIRH;
245
246 return @f;
9c5c68c8 247}
248
b82fa0b7 249=item B<_run_all_tests>
250
251 my($total, $failed) = _run_all_tests(@test_files);
252
e4fc8a1e 253Runs all the given C<@test_files> (as C<runtests()>) but does it
254quietly (no report). $total is a hash ref summary of all the tests
255run. Its keys and values are this:
b82fa0b7 256
257 bonus Number of individual todo tests unexpectedly passed
258 max Number of individual tests ran
259 ok Number of individual tests passed
260 sub_skipped Number of individual tests skipped
2fe373ce 261 todo Number of individual todo tests
b82fa0b7 262
263 files Number of test files ran
264 good Number of test files passed
265 bad Number of test files failed
266 tests Number of test files originally given
267 skipped Number of test files skipped
268
e4fc8a1e 269If C<< $total->{bad} == 0 >> and C<< $total->{max} > 0 >>, you've
270got a successful test.
b82fa0b7 271
272$failed is a hash ref of all the test scripts which failed. Each key
273is the name of a test script, each value is another hash representing
274how that script failed. Its keys are these:
9c5c68c8 275
b82fa0b7 276 name Name of the test which failed
277 estat Script's exit value
278 wstat Script's wait status
279 max Number of individual tests
280 failed Number which failed
281 percent Percentage of tests which failed
282 canon List of tests which failed (as string).
283
e4fc8a1e 284C<$failed> should be empty if everything passed.
b82fa0b7 285
286B<NOTE> Currently this function is still noisy. I'm working on it.
287
288=cut
289
3c87ea76 290# Turns on autoflush for the handle passed
291sub _autoflush {
292 my $flushy_fh = shift;
293 my $old_fh = select $flushy_fh;
294 $| = 1;
295 select $old_fh;
296}
297
b82fa0b7 298sub _run_all_tests {
3c87ea76 299 my @tests = @_;
300
301 _autoflush(\*STDOUT);
302 _autoflush(\*STDERR);
303
9c5c68c8 304 my(%failedtests);
305
306 # Test-wide totals.
307 my(%tot) = (
308 bonus => 0,
309 max => 0,
310 ok => 0,
311 files => 0,
312 bad => 0,
313 good => 0,
314 tests => scalar @tests,
315 sub_skipped => 0,
2fe373ce 316 todo => 0,
9c5c68c8 317 skipped => 0,
2fe373ce 318 bench => 0,
9c5c68c8 319 );
774d564b 320
76df5e8f 321 my @dir_files;
322 @dir_files = _globdir $Files_In_Dir if defined $Files_In_Dir;
a0d0e21e 323 my $t_start = new Benchmark;
9c5c68c8 324
13287dd5 325 my $width = _leader_width(@tests);
b82fa0b7 326 foreach my $tfile (@tests) {
5c0604c3 327 $Last_ML_Print = 0; # so each test prints at least once
7a315204 328 my($leader, $ml) = _mk_leader($tfile, $width);
308957f5 329 local $ML = $ml;
e4fc8a1e 330
b82fa0b7 331 print $leader;
9c5c68c8 332
356733da 333 $tot{files}++;
334
308957f5 335 $Strap->{_seen_header} = 0;
3c87ea76 336 if ( $Test::Harness::Debug ) {
337 print "# Running: ", $Strap->_command_line($tfile), "\n";
338 }
0be28027 339 my %results = $Strap->analyze_file($tfile) or
e4fc8a1e 340 do { warn $Strap->{error}, "\n"; next };
308957f5 341
9c5c68c8 342 # state of the current test.
308957f5 343 my @failed = grep { !$results{details}[$_-1]{ok} }
344 1..@{$results{details}};
9c5c68c8 345 my %test = (
308957f5 346 ok => $results{ok},
347 'next' => $Strap->{'next'},
348 max => $results{max},
349 failed => \@failed,
350 bonus => $results{bonus},
351 skipped => $results{skip},
a72fde19 352 skip_reason => $results{skip_reason},
c0bb2de7 353 skip_all => $Strap->{skip_all},
9c5c68c8 354 ml => $ml,
355 );
356
308957f5 357 $tot{bonus} += $results{bonus};
358 $tot{max} += $results{max};
359 $tot{ok} += $results{ok};
360 $tot{todo} += $results{todo};
361 $tot{sub_skipped} += $results{skip};
9c5c68c8 362
308957f5 363 my($estatus, $wstatus) = @results{qw(exit wait)};
b82fa0b7 364
a72fde19 365 if ($results{passing}) {
2fe373ce 366 if ($test{max} and $test{skipped} + $test{bonus}) {
367 my @msg;
368 push(@msg, "$test{skipped}/$test{max} skipped: $test{skip_reason}")
369 if $test{skipped};
370 push(@msg, "$test{bonus}/$test{max} unexpectedly succeeded")
371 if $test{bonus};
f0008e52 372 print "$test{ml}ok\n ".join(', ', @msg)."\n";
2fe373ce 373 } elsif ($test{max}) {
374 print "$test{ml}ok\n";
d5d4ec93 375 } elsif (defined $test{skip_all} and length $test{skip_all}) {
c0bb2de7 376 print "skipped\n all skipped: $test{skip_all}\n";
2fe373ce 377 $tot{skipped}++;
378 } else {
0be28027 379 print "skipped\n all skipped: no reason given\n";
2fe373ce 380 $tot{skipped}++;
381 }
382 $tot{good}++;
383 }
b82fa0b7 384 else {
a72fde19 385 # List unrun tests as failures.
386 if ($test{'next'} <= $test{max}) {
387 push @{$test{failed}}, $test{'next'}..$test{max};
388 }
389 # List overruns as failures.
390 else {
391 my $details = $results{details};
3c87ea76 392 foreach my $overrun ($test{max}+1..@$details) {
a72fde19 393 next unless ref $details->[$overrun-1];
394 push @{$test{failed}}, $overrun
b82fa0b7 395 }
a72fde19 396 }
397
398 if ($wstatus) {
399 $failedtests{$tfile} = _dubious_return(\%test, \%tot,
400 $estatus, $wstatus);
401 $failedtests{$tfile}{name} = $tfile;
402 }
403 elsif($results{seen}) {
c4b2e1b6 404 if (@{$test{failed}} and $test{max}) {
60e33a80 405 my ($txt, $canon) = _canonfailed($test{max},$test{skipped},
b82fa0b7 406 @{$test{failed}});
407 print "$test{ml}$txt";
408 $failedtests{$tfile} = { canon => $canon,
409 max => $test{max},
410 failed => scalar @{$test{failed}},
411 name => $tfile,
412 percent => 100*(scalar @{$test{failed}})/$test{max},
413 estat => '',
414 wstat => '',
415 };
416 } else {
417 print "Don't know which tests failed: got $test{ok} ok, ".
418 "expected $test{max}\n";
419 $failedtests{$tfile} = { canon => '??',
420 max => $test{max},
421 failed => '??',
422 name => $tfile,
423 percent => undef,
424 estat => '',
425 wstat => '',
426 };
427 }
428 $tot{bad}++;
a72fde19 429 } else {
b82fa0b7 430 print "FAILED before any test output arrived\n";
431 $tot{bad}++;
432 $failedtests{$tfile} = { canon => '??',
433 max => '??',
434 failed => '??',
435 name => $tfile,
436 percent => undef,
437 estat => '',
438 wstat => '',
439 };
440 }
441 }
442
2fe373ce 443 if (defined $Files_In_Dir) {
444 my @new_dir_files = _globdir $Files_In_Dir;
445 if (@new_dir_files != @dir_files) {
446 my %f;
447 @f{@new_dir_files} = (1) x @new_dir_files;
448 delete @f{@dir_files};
449 my @f = sort keys %f;
450 print "LEAKED FILES: @f\n";
451 @dir_files = @new_dir_files;
452 }
453 }
3c87ea76 454 } # foreach test
9c5c68c8 455 $tot{bench} = timediff(new Benchmark, $t_start);
d667a7e6 456
13287dd5 457 $Strap->_restore_PERL5LIB;
9c5c68c8 458
459 return(\%tot, \%failedtests);
460}
461
b82fa0b7 462=item B<_mk_leader>
463
7a315204 464 my($leader, $ml) = _mk_leader($test_file, $width);
b82fa0b7 465
3c87ea76 466Generates the 't/foo........' leader for the given C<$test_file> as well
b82fa0b7 467as a similar version which will overwrite the current line (by use of
e4fc8a1e 468\r and such). C<$ml> may be empty if Test::Harness doesn't think you're
2fe373ce 469on TTY.
470
e4fc8a1e 471The C<$width> is the width of the "yada/blah.." string.
b82fa0b7 472
473=cut
474
475sub _mk_leader {
2fe373ce 476 my($te, $width) = @_;
477 chomp($te);
b695f709 478 $te =~ s/\.\w+$/./;
b82fa0b7 479
356733da 480 if ($^O eq 'VMS') { $te =~ s/^.*\.t\./\[.t./s; }
b82fa0b7 481 my $blank = (' ' x 77);
7a315204 482 my $leader = "$te" . '.' x ($width - length($te));
b82fa0b7 483 my $ml = "";
484
485 $ml = "\r$blank\r$leader"
486 if -t STDOUT and not $ENV{HARNESS_NOTTY} and not $Verbose;
487
488 return($leader, $ml);
489}
490
13287dd5 491=item B<_leader_width>
492
493 my($width) = _leader_width(@test_files);
494
495Calculates how wide the leader should be based on the length of the
496longest test name.
497
498=cut
499
500sub _leader_width {
501 my $maxlen = 0;
502 my $maxsuflen = 0;
503 foreach (@_) {
504 my $suf = /\.(\w+)$/ ? $1 : '';
505 my $len = length;
506 my $suflen = length $suf;
507 $maxlen = $len if $len > $maxlen;
508 $maxsuflen = $suflen if $suflen > $maxsuflen;
509 }
356733da 510 # + 3 : we want three dots between the test name and the "ok"
511 return $maxlen + 3 - $maxsuflen;
13287dd5 512}
513
9c5c68c8 514
515sub _show_results {
516 my($tot, $failedtests) = @_;
517
518 my $pct;
519 my $bonusmsg = _bonusmsg($tot);
520
2fe373ce 521 if (_all_ok($tot)) {
522 print "All tests successful$bonusmsg.\n";
523 } elsif (!$tot->{tests}){
524 die "FAILED--no tests were run for some reason.\n";
525 } elsif (!$tot->{max}) {
526 my $blurb = $tot->{tests}==1 ? "script" : "scripts";
527 die "FAILED--$tot->{tests} test $blurb could be run, ".
9c5c68c8 528 "alas--no output ever seen\n";
c07a80fd 529 } else {
2fe373ce 530 $pct = sprintf("%.2f", $tot->{good} / $tot->{tests} * 100);
531 my $percent_ok = 100*$tot->{ok}/$tot->{max};
532 my $subpct = sprintf " %d/%d subtests failed, %.2f%% okay.",
533 $tot->{max} - $tot->{ok}, $tot->{max},
534 $percent_ok;
0a931e4a 535
9c5c68c8 536 my($fmt_top, $fmt) = _create_fmts($failedtests);
0a931e4a 537
2fe373ce 538 # Now write to formats
539 for my $script (sort keys %$failedtests) {
540 $Curtest = $failedtests->{$script};
541 write;
542 }
543 if ($tot->{bad}) {
544 $bonusmsg =~ s/^,\s*//;
545 print "$bonusmsg.\n" if $bonusmsg;
546 die "Failed $tot->{bad}/$tot->{tests} test scripts, $pct% okay.".
9c5c68c8 547 "$subpct\n";
2fe373ce 548 }
c07a80fd 549 }
f0a9308e 550
9c5c68c8 551 printf("Files=%d, Tests=%d, %s\n",
552 $tot->{files}, $tot->{max}, timestr($tot->{bench}, 'nop'));
553}
554
555
3c87ea76 556my %Handlers = (
557 header => \&header_handler,
558 test => \&test_handler,
559 bailout => \&bailout_handler,
560);
561
562$Strap->{callback} = \&strap_callback;
563sub strap_callback {
308957f5 564 my($self, $line, $type, $totals) = @_;
565 print $line if $Verbose;
9c5c68c8 566
308957f5 567 my $meth = $Handlers{$type};
568 $meth->($self, $line, $type, $totals) if $meth;
569};
9c5c68c8 570
9c5c68c8 571
3c87ea76 572sub header_handler {
308957f5 573 my($self, $line, $type, $totals) = @_;
9c5c68c8 574
308957f5 575 warn "Test header seen more than once!\n" if $self->{_seen_header};
9c5c68c8 576
308957f5 577 $self->{_seen_header}++;
9c5c68c8 578
308957f5 579 warn "1..M can only appear at the beginning or end of tests\n"
580 if $totals->{seen} &&
581 $totals->{max} < $totals->{seen};
582};
13287dd5 583
3c87ea76 584sub test_handler {
308957f5 585 my($self, $line, $type, $totals) = @_;
9c5c68c8 586
308957f5 587 my $curr = $totals->{seen};
588 my $next = $self->{'next'};
589 my $max = $totals->{max};
590 my $detail = $totals->{details}[-1];
b82fa0b7 591
308957f5 592 if( $detail->{ok} ) {
5c0604c3 593 _print_ml_less("ok $curr/$max");
356733da 594
308957f5 595 if( $detail->{type} eq 'skip' ) {
a72fde19 596 $totals->{skip_reason} = $detail->{reason}
597 unless defined $totals->{skip_reason};
598 $totals->{skip_reason} = 'various reasons'
599 if $totals->{skip_reason} ne $detail->{reason};
308957f5 600 }
b82fa0b7 601 }
602 else {
308957f5 603 _print_ml("NOK $curr");
b82fa0b7 604 }
b82fa0b7 605
308957f5 606 if( $curr > $next ) {
607 print "Test output counter mismatch [test $curr]\n";
608 }
609 elsif( $curr < $next ) {
610 print "Confused test output: test $curr answered after ".
611 "test ", $next - 1, "\n";
612 }
b82fa0b7 613
308957f5 614};
2fe373ce 615
3c87ea76 616sub bailout_handler {
308957f5 617 my($self, $line, $type, $totals) = @_;
9c5c68c8 618
308957f5 619 die "FAILED--Further testing stopped" .
620 ($self->{bailout_reason} ? ": $self->{bailout_reason}\n" : ".\n");
621};
356733da 622
9c5c68c8 623
308957f5 624sub _print_ml {
625 print join '', $ML, @_ if $ML;
9c5c68c8 626}
627
628
5c0604c3 629# For slow connections, we save lots of bandwidth by printing only once
630# per second.
631sub _print_ml_less {
3c87ea76 632 if ( $Last_ML_Print != time ) {
5c0604c3 633 _print_ml(@_);
634 $Last_ML_Print = time;
635 }
636}
637
9c5c68c8 638sub _bonusmsg {
639 my($tot) = @_;
640
641 my $bonusmsg = '';
642 $bonusmsg = (" ($tot->{bonus} subtest".($tot->{bonus} > 1 ? 's' : '').
2fe373ce 643 " UNEXPECTEDLY SUCCEEDED)")
644 if $tot->{bonus};
9c5c68c8 645
646 if ($tot->{skipped}) {
2fe373ce 647 $bonusmsg .= ", $tot->{skipped} test"
9c5c68c8 648 . ($tot->{skipped} != 1 ? 's' : '');
2fe373ce 649 if ($tot->{sub_skipped}) {
650 $bonusmsg .= " and $tot->{sub_skipped} subtest"
651 . ($tot->{sub_skipped} != 1 ? 's' : '');
652 }
653 $bonusmsg .= ' skipped';
9c5c68c8 654 }
655 elsif ($tot->{sub_skipped}) {
2fe373ce 656 $bonusmsg .= ", $tot->{sub_skipped} subtest"
657 . ($tot->{sub_skipped} != 1 ? 's' : '')
658 . " skipped";
9c5c68c8 659 }
660
661 return $bonusmsg;
662}
663
9c5c68c8 664# Test program go boom.
665sub _dubious_return {
666 my($test, $tot, $estatus, $wstatus) = @_;
667 my ($failed, $canon, $percent) = ('??', '??');
668
669 printf "$test->{ml}dubious\n\tTest returned status $estatus ".
670 "(wstat %d, 0x%x)\n",
671 $wstatus,$wstatus;
672 print "\t\t(VMS status is $estatus)\n" if $^O eq 'VMS';
673
9c5c68c8 674 $tot->{bad}++;
675
676 if ($test->{max}) {
b82fa0b7 677 if ($test->{'next'} == $test->{max} + 1 and not @{$test->{failed}}) {
9c5c68c8 678 print "\tafter all the subtests completed successfully\n";
679 $percent = 0;
2fe373ce 680 $failed = 0; # But we do not set $canon!
9c5c68c8 681 }
682 else {
b82fa0b7 683 push @{$test->{failed}}, $test->{'next'}..$test->{max};
9c5c68c8 684 $failed = @{$test->{failed}};
60e33a80 685 (my $txt, $canon) = _canonfailed($test->{max},$test->{skipped},@{$test->{failed}});
9c5c68c8 686 $percent = 100*(scalar @{$test->{failed}})/$test->{max};
687 print "DIED. ",$txt;
688 }
689 }
690
691 return { canon => $canon, max => $test->{max} || '??',
692 failed => $failed,
66fd8cb9 693 percent => $percent,
9c5c68c8 694 estat => $estatus, wstat => $wstatus,
695 };
696}
697
698
9c5c68c8 699sub _create_fmts {
700 my($failedtests) = @_;
701
b82fa0b7 702 my $failed_str = "Failed Test";
703 my $middle_str = " Stat Wstat Total Fail Failed ";
9c5c68c8 704 my $list_str = "List of Failed";
705
706 # Figure out our longest name string for formatting purposes.
707 my $max_namelen = length($failed_str);
708 foreach my $script (keys %$failedtests) {
709 my $namelen = length $failedtests->{$script}->{name};
710 $max_namelen = $namelen if $namelen > $max_namelen;
711 }
712
713 my $list_len = $Columns - length($middle_str) - $max_namelen;
714 if ($list_len < length($list_str)) {
715 $list_len = length($list_str);
716 $max_namelen = $Columns - length($middle_str) - $list_len;
717 if ($max_namelen < length($failed_str)) {
718 $max_namelen = length($failed_str);
719 $Columns = $max_namelen + length($middle_str) + $list_len;
720 }
721 }
722
723 my $fmt_top = "format STDOUT_TOP =\n"
b82fa0b7 724 . sprintf("%-${max_namelen}s", $failed_str)
9c5c68c8 725 . $middle_str
2fe373ce 726 . $list_str . "\n"
727 . "-" x $Columns
728 . "\n.\n";
9c5c68c8 729
730 my $fmt = "format STDOUT =\n"
2fe373ce 731 . "@" . "<" x ($max_namelen - 1)
b82fa0b7 732 . " @>> @>>>> @>>>> @>>> ^##.##% "
2fe373ce 733 . "^" . "<" x ($list_len - 1) . "\n"
734 . '{ $Curtest->{name}, $Curtest->{estat},'
735 . ' $Curtest->{wstat}, $Curtest->{max},'
736 . ' $Curtest->{failed}, $Curtest->{percent},'
737 . ' $Curtest->{canon}'
738 . "\n}\n"
739 . "~~" . " " x ($Columns - $list_len - 2) . "^"
740 . "<" x ($list_len - 1) . "\n"
741 . '$Curtest->{canon}'
742 . "\n.\n";
9c5c68c8 743
744 eval $fmt_top;
745 die $@ if $@;
746 eval $fmt;
747 die $@ if $@;
748
749 return($fmt_top, $fmt);
750}
751
60e33a80 752sub _canonfailed ($$@) {
89d3b7e2 753 my($max,$skipped,@failed) = @_;
6c31b336 754 my %seen;
755 @failed = sort {$a <=> $b} grep !$seen{$_}++, @failed;
c07a80fd 756 my $failed = @failed;
757 my @result = ();
758 my @canon = ();
759 my $min;
760 my $last = $min = shift @failed;
760ac839 761 my $canon;
c07a80fd 762 if (@failed) {
2fe373ce 763 for (@failed, $failed[-1]) { # don't forget the last one
764 if ($_ > $last+1 || $_ == $last) {
765 if ($min == $last) {
766 push @canon, $last;
767 } else {
768 push @canon, "$min-$last";
769 }
770 $min = $_;
771 }
772 $last = $_;
773 }
774 local $" = ", ";
775 push @result, "FAILED tests @canon\n";
776 $canon = join ' ', @canon;
a0d0e21e 777 } else {
2fe373ce 778 push @result, "FAILED test $last\n";
779 $canon = $last;
a0d0e21e 780 }
c07a80fd 781
782 push @result, "\tFailed $failed/$max tests, ";
e93c2686 783 if ($max) {
784 push @result, sprintf("%.2f",100*(1-$failed/$max)), "% okay";
785 } else {
786 push @result, "?% okay";
787 }
89d3b7e2 788 my $ender = 's' x ($skipped > 1);
e93c2686 789 if ($skipped) {
3c87ea76 790 my $good = $max - $failed - $skipped;
e93c2686 791 my $skipmsg = " (less $skipped skipped test$ender: $good okay, ";
792 if ($max) {
793 my $goodper = sprintf("%.2f",100*($good/$max));
794 $skipmsg .= "$goodper%)";
795 } else {
796 $skipmsg .= "?%)";
797 }
798 push @result, $skipmsg;
799 }
89d3b7e2 800 push @result, "\n";
760ac839 801 my $txt = join "", @result;
802 ($txt, $canon);
a0d0e21e 803}
804
b82fa0b7 805=end _private
9c5c68c8 806
b82fa0b7 807=back
d667a7e6 808
b82fa0b7 809=cut
9c5c68c8 810
9c5c68c8 811
b82fa0b7 8121;
813__END__
9c5c68c8 814
815
cb1a09d0 816=head1 EXPORT
817
e8df9912 818C<&runtests> is exported by Test::Harness by default.
cb1a09d0 819
e4fc8a1e 820C<$verbose>, C<$switches> and C<$debug> are exported upon request.
9c5c68c8 821
cb1a09d0 822=head1 DIAGNOSTICS
823
824=over 4
825
826=item C<All tests successful.\nFiles=%d, Tests=%d, %s>
827
828If all tests are successful some statistics about the performance are
829printed.
830
6c31b336 831=item C<FAILED tests %s\n\tFailed %d/%d tests, %.2f%% okay.>
832
833For any single script that has failing subtests statistics like the
834above are printed.
835
836=item C<Test returned status %d (wstat %d)>
837
9c5c68c8 838Scripts that return a non-zero exit status, both C<$? E<gt>E<gt> 8>
839and C<$?> are printed in a message similar to the above.
6c31b336 840
841=item C<Failed 1 test, %.2f%% okay. %s>
cb1a09d0 842
6c31b336 843=item C<Failed %d/%d tests, %.2f%% okay. %s>
cb1a09d0 844
845If not all tests were successful, the script dies with one of the
846above messages.
847
308957f5 848=item C<FAILED--Further testing stopped: %s>
d667a7e6 849
850If a single subtest decides that further testing will not make sense,
851the script dies with this message.
852
cb1a09d0 853=back
854
9b0ceca9 855=head1 ENVIRONMENT
856
37ce32a7 857=over 4
858
356733da 859=item C<HARNESS_ACTIVE>
37ce32a7 860
356733da 861Harness sets this before executing the individual tests. This allows
862the tests to determine if they are being executed through the harness
863or by any other means.
37ce32a7 864
356733da 865=item C<HARNESS_COLUMNS>
9b0ceca9 866
356733da 867This value will be used for the width of the terminal. If it is not
868set then it will default to C<COLUMNS>. If this is not set, it will
869default to 80. Note that users of Bourne-sh based shells will need to
870C<export COLUMNS> for this module to use that variable.
0d0c0d42 871
b82fa0b7 872=item C<HARNESS_COMPILE_TEST>
9636a016 873
37ce32a7 874When true it will make harness attempt to compile the test using
875C<perlcc> before running it.
876
b82fa0b7 877B<NOTE> This currently only works when sitting in the perl source
878directory!
879
e4fc8a1e 880=item C<HARNESS_DEBUG>
881
882If true, Test::Harness will print debugging information about itself as
883it runs the tests. This is different from C<HARNESS_VERBOSE>, which prints
884the output from the test being run. Setting C<$Test::Harness::Debug> will
885override this, or you can use the C<-d> switch in the F<prove> utility.
886
b82fa0b7 887=item C<HARNESS_FILELEAK_IN_DIR>
37ce32a7 888
889When set to the name of a directory, harness will check after each
890test whether new files appeared in that directory, and report them as
17a79f5b 891
892 LEAKED FILES: scr.tmp 0 my.db
893
894If relative, directory name is with respect to the current directory at
895the moment runtests() was called. Putting absolute path into
13287dd5 896C<HARNESS_FILELEAK_IN_DIR> may give more predictable results.
17a79f5b 897
356733da 898=item C<HARNESS_IGNORE_EXITCODE>
899
900Makes harness ignore the exit status of child processes when defined.
901
902=item C<HARNESS_NOTTY>
903
904When set to a true value, forces it to behave as though STDOUT were
905not a console. You may need to set this if you don't want harness to
906output more frequent progress messages using carriage returns. Some
907consoles may not handle carriage returns properly (which results in a
908somewhat messy output).
909
e4fc8a1e 910=item C<HARNESS_PERL>
911
912Usually your tests will be run by C<$^X>, the currently-executing Perl.
913However, you may want to have it run by a different executable, such as
914a threading perl, or a different version.
915
916If you're using the F<prove> utility, you can use the C<--perl> switch.
60af4b93 917
b82fa0b7 918=item C<HARNESS_PERL_SWITCHES>
37ce32a7 919
920Its value will be prepended to the switches used to invoke perl on
b82fa0b7 921each test. For example, setting C<HARNESS_PERL_SWITCHES> to C<-W> will
37ce32a7 922run all tests with all warnings enabled.
923
356733da 924=item C<HARNESS_VERBOSE>
37ce32a7 925
356733da 926If true, Test::Harness will output the verbose results of running
e4fc8a1e 927its tests. Setting C<$Test::Harness::verbose> will override this,
928or you can use the C<-v> switch in the F<prove> utility.
37ce32a7 929
930=back
0a931e4a 931
b82fa0b7 932=head1 EXAMPLE
933
934Here's how Test::Harness tests itself
935
936 $ cd ~/src/devel/Test-Harness
937 $ perl -Mblib -e 'use Test::Harness qw(&runtests $verbose);
938 $verbose=0; runtests @ARGV;' t/*.t
939 Using /home/schwern/src/devel/Test-Harness/blib
940 t/base..............ok
941 t/nonumbers.........ok
942 t/ok................ok
943 t/test-harness......ok
944 All tests successful.
945 Files=4, Tests=24, 2 wallclock secs ( 0.61 cusr + 0.41 csys = 1.02 CPU)
f19ae7a7 946
cb1a09d0 947=head1 SEE ALSO
948
42d29bac 949The included F<prove> utility for running test scripts from the command line,
b82fa0b7 950L<Test> and L<Test::Simple> for writing test scripts, L<Benchmark> for
3c87ea76 951the underlying timing routines, and L<Devel::Cover> for test coverage
b82fa0b7 952analysis.
c07a80fd 953
b82fa0b7 954=head1 TODO
955
956Provide a way of running tests quietly (ie. no printing) for automated
957validation of tests. This will probably take the form of a version
958of runtests() which rather than printing its output returns raw data
356733da 959on the state of the tests. (Partially done in Test::Harness::Straps)
b82fa0b7 960
cf2ab31a 961Document the format.
962
b82fa0b7 963Fix HARNESS_COMPILE_TEST without breaking its core usage.
964
965Figure a way to report test names in the failure summary.
37ce32a7 966
b82fa0b7 967Rework the test summary so long test names are not truncated as badly.
308957f5 968(Partially done with new skip test styles)
b82fa0b7 969
b82fa0b7 970Add option for coverage analysis.
971
cf2ab31a 972Trap STDERR.
973
974Implement Straps total_results()
975
976Remember exit code
977
978Completely redo the print summary code.
979
980Implement Straps callbacks. (experimentally implemented)
981
982Straps->analyze_file() not taint clean, don't know if it can be
983
984Fix that damned VMS nit.
985
986HARNESS_TODOFAIL to display TODO failures
987
988Add a test for verbose.
989
990Change internal list of test results to a hash.
991
992Fix stats display when there's an overrun.
993
994Fix so perls with spaces in the filename work.
995
b82fa0b7 996Keeping whittling away at _run_all_tests()
997
b82fa0b7 998Clean up how the summary is printed. Get rid of those damned formats.
cb1a09d0 999
1000=head1 BUGS
1001
356733da 1002HARNESS_COMPILE_TEST currently assumes it's run from the Perl source
b82fa0b7 1003directory.
1004
e4fc8a1e 1005Please use the CPAN bug ticketing system at L<http://rt.cpan.org/>.
1006You can also mail bugs, fixes and enhancements to
3c87ea76 1007C<< <bug-test-harness >> at C<< rt.cpan.org> >>.
e4fc8a1e 1008
1009=head1 AUTHORS
1010
3c87ea76 1011Either Tim Bunce or Andreas Koenig, we don't know. What we know for
1012sure is, that it was inspired by Larry Wall's TEST script that came
1013with perl distributions for ages. Numerous anonymous contributors
1014exist. Andreas Koenig held the torch for many years, and then
1015Michael G Schwern.
1016
1017Current maintainer is Andy Lester C<< <andy at petdance.com> >>.
e4fc8a1e 1018
1019=head1 COPYRIGHT
1020
3c87ea76 1021Copyright 2002-2005
1022by Michael G Schwern C<< <schwern at pobox.com> >>,
1023Andy Lester C<< <andy at petdance.com> >>.
e4fc8a1e 1024
1025This program is free software; you can redistribute it and/or
1026modify it under the same terms as Perl itself.
1027
1028See L<http://www.perl.com/perl/misc/Artistic.html>.
1029
cb1a09d0 1030=cut