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