source: for-distributions/trunk/bin/windows/perl/lib/Test/Harness.pm@ 14489

Last change on this file since 14489 was 14489, checked in by oranfry, 17 years ago

upgrading to perl 5.8

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