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 1081