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