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