1*0Sstevel@tonic-gatepackage Test::More; 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gateuse 5.004; 4*0Sstevel@tonic-gate 5*0Sstevel@tonic-gateuse strict; 6*0Sstevel@tonic-gateuse Test::Builder; 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gate# Can't use Carp because it might cause use_ok() to accidentally succeed 10*0Sstevel@tonic-gate# even though the module being used forgot to use Carp. Yes, this 11*0Sstevel@tonic-gate# actually happened. 12*0Sstevel@tonic-gatesub _carp { 13*0Sstevel@tonic-gate my($file, $line) = (caller(1))[1,2]; 14*0Sstevel@tonic-gate warn @_, " at $file line $line\n"; 15*0Sstevel@tonic-gate} 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gaterequire Exporter; 20*0Sstevel@tonic-gateuse vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS $TODO); 21*0Sstevel@tonic-gate$VERSION = '0.47'; 22*0Sstevel@tonic-gate@ISA = qw(Exporter); 23*0Sstevel@tonic-gate@EXPORT = qw(ok use_ok require_ok 24*0Sstevel@tonic-gate is isnt like unlike is_deeply 25*0Sstevel@tonic-gate cmp_ok 26*0Sstevel@tonic-gate skip todo todo_skip 27*0Sstevel@tonic-gate pass fail 28*0Sstevel@tonic-gate eq_array eq_hash eq_set 29*0Sstevel@tonic-gate $TODO 30*0Sstevel@tonic-gate plan 31*0Sstevel@tonic-gate can_ok isa_ok 32*0Sstevel@tonic-gate diag 33*0Sstevel@tonic-gate ); 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gatemy $Test = Test::Builder->new; 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate# 5.004's Exporter doesn't have export_to_level. 39*0Sstevel@tonic-gatesub _export_to_level 40*0Sstevel@tonic-gate{ 41*0Sstevel@tonic-gate my $pkg = shift; 42*0Sstevel@tonic-gate my $level = shift; 43*0Sstevel@tonic-gate (undef) = shift; # redundant arg 44*0Sstevel@tonic-gate my $callpkg = caller($level); 45*0Sstevel@tonic-gate $pkg->export($callpkg, @_); 46*0Sstevel@tonic-gate} 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate=head1 NAME 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gateTest::More - yet another framework for writing test scripts 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate=head1 SYNOPSIS 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate use Test::More tests => $Num_Tests; 56*0Sstevel@tonic-gate # or 57*0Sstevel@tonic-gate use Test::More qw(no_plan); 58*0Sstevel@tonic-gate # or 59*0Sstevel@tonic-gate use Test::More skip_all => $reason; 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate BEGIN { use_ok( 'Some::Module' ); } 62*0Sstevel@tonic-gate require_ok( 'Some::Module' ); 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate # Various ways to say "ok" 65*0Sstevel@tonic-gate ok($this eq $that, $test_name); 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate is ($this, $that, $test_name); 68*0Sstevel@tonic-gate isnt($this, $that, $test_name); 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate # Rather than print STDERR "# here's what went wrong\n" 71*0Sstevel@tonic-gate diag("here's what went wrong"); 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate like ($this, qr/that/, $test_name); 74*0Sstevel@tonic-gate unlike($this, qr/that/, $test_name); 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate cmp_ok($this, '==', $that, $test_name); 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate is_deeply($complex_structure1, $complex_structure2, $test_name); 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate SKIP: { 81*0Sstevel@tonic-gate skip $why, $how_many unless $have_some_feature; 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate ok( foo(), $test_name ); 84*0Sstevel@tonic-gate is( foo(42), 23, $test_name ); 85*0Sstevel@tonic-gate }; 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate TODO: { 88*0Sstevel@tonic-gate local $TODO = $why; 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate ok( foo(), $test_name ); 91*0Sstevel@tonic-gate is( foo(42), 23, $test_name ); 92*0Sstevel@tonic-gate }; 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate can_ok($module, @methods); 95*0Sstevel@tonic-gate isa_ok($object, $class); 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate pass($test_name); 98*0Sstevel@tonic-gate fail($test_name); 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate # Utility comparison functions. 101*0Sstevel@tonic-gate eq_array(\@this, \@that); 102*0Sstevel@tonic-gate eq_hash(\%this, \%that); 103*0Sstevel@tonic-gate eq_set(\@this, \@that); 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate # UNIMPLEMENTED!!! 106*0Sstevel@tonic-gate my @status = Test::More::status; 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate # UNIMPLEMENTED!!! 109*0Sstevel@tonic-gate BAIL_OUT($why); 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate=head1 DESCRIPTION 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gateB<STOP!> If you're just getting started writing tests, have a look at 115*0Sstevel@tonic-gateTest::Simple first. This is a drop in replacement for Test::Simple 116*0Sstevel@tonic-gatewhich you can switch to once you get the hang of basic testing. 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gateThe purpose of this module is to provide a wide range of testing 119*0Sstevel@tonic-gateutilities. Various ways to say "ok" with better diagnostics, 120*0Sstevel@tonic-gatefacilities to skip tests, test future features and compare complicated 121*0Sstevel@tonic-gatedata structures. While you can do almost anything with a simple 122*0Sstevel@tonic-gateC<ok()> function, it doesn't provide good diagnostic output. 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate=head2 I love it when a plan comes together 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gateBefore anything else, you need a testing plan. This basically declares 128*0Sstevel@tonic-gatehow many tests your script is going to run to protect against premature 129*0Sstevel@tonic-gatefailure. 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gateThe preferred way to do this is to declare a plan when you C<use Test::More>. 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate use Test::More tests => $Num_Tests; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gateThere are rare cases when you will not know beforehand how many tests 136*0Sstevel@tonic-gateyour script is going to run. In this case, you can declare that you 137*0Sstevel@tonic-gatehave no plan. (Try to avoid using this as it weakens your test.) 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate use Test::More qw(no_plan); 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gateIn some cases, you'll want to completely skip an entire testing script. 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate use Test::More skip_all => $skip_reason; 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gateYour script will declare a skip with the reason why you skipped and 146*0Sstevel@tonic-gateexit immediately with a zero (success). See L<Test::Harness> for 147*0Sstevel@tonic-gatedetails. 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gateIf you want to control what functions Test::More will export, you 150*0Sstevel@tonic-gatehave to use the 'import' option. For example, to import everything 151*0Sstevel@tonic-gatebut 'fail', you'd do: 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate use Test::More tests => 23, import => ['!fail']; 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gateAlternatively, you can use the plan() function. Useful for when you 156*0Sstevel@tonic-gatehave to calculate the number of tests. 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gate use Test::More; 159*0Sstevel@tonic-gate plan tests => keys %Stuff * 3; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gateor for deciding between running the tests at all: 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate use Test::More; 164*0Sstevel@tonic-gate if( $^O eq 'MacOS' ) { 165*0Sstevel@tonic-gate plan skip_all => 'Test irrelevant on MacOS'; 166*0Sstevel@tonic-gate } 167*0Sstevel@tonic-gate else { 168*0Sstevel@tonic-gate plan tests => 42; 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate=cut 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gatesub plan { 174*0Sstevel@tonic-gate my(@plan) = @_; 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate my $caller = caller; 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate $Test->exported_to($caller); 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate my @imports = (); 181*0Sstevel@tonic-gate foreach my $idx (0..$#plan) { 182*0Sstevel@tonic-gate if( $plan[$idx] eq 'import' ) { 183*0Sstevel@tonic-gate my($tag, $imports) = splice @plan, $idx, 2; 184*0Sstevel@tonic-gate @imports = @$imports; 185*0Sstevel@tonic-gate last; 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate } 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate $Test->plan(@plan); 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate __PACKAGE__->_export_to_level(1, __PACKAGE__, @imports); 192*0Sstevel@tonic-gate} 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gatesub import { 195*0Sstevel@tonic-gate my($class) = shift; 196*0Sstevel@tonic-gate goto &plan; 197*0Sstevel@tonic-gate} 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate=head2 Test names 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gateBy convention, each test is assigned a number in order. This is 203*0Sstevel@tonic-gatelargely done automatically for you. However, it's often very useful to 204*0Sstevel@tonic-gateassign a name to each test. Which would you rather see: 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate ok 4 207*0Sstevel@tonic-gate not ok 5 208*0Sstevel@tonic-gate ok 6 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gateor 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate ok 4 - basic multi-variable 213*0Sstevel@tonic-gate not ok 5 - simple exponential 214*0Sstevel@tonic-gate ok 6 - force == mass * acceleration 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gateThe later gives you some idea of what failed. It also makes it easier 217*0Sstevel@tonic-gateto find the test in your script, simply search for "simple 218*0Sstevel@tonic-gateexponential". 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gateAll test functions take a name argument. It's optional, but highly 221*0Sstevel@tonic-gatesuggested that you use it. 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate=head2 I'm ok, you're not ok. 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gateThe basic purpose of this module is to print out either "ok #" or "not 227*0Sstevel@tonic-gateok #" depending on if a given test succeeded or failed. Everything 228*0Sstevel@tonic-gateelse is just gravy. 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gateAll of the following print "ok" or "not ok" depending on if the test 231*0Sstevel@tonic-gatesucceeded or failed. They all also return true or false, 232*0Sstevel@tonic-gaterespectively. 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate=over 4 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate=item B<ok> 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate ok($this eq $that, $test_name); 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gateThis simply evaluates any expression (C<$this eq $that> is just a 241*0Sstevel@tonic-gatesimple example) and uses that to determine if the test succeeded or 242*0Sstevel@tonic-gatefailed. A true expression passes, a false one fails. Very simple. 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gateFor example: 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate ok( $exp{9} == 81, 'simple exponential' ); 247*0Sstevel@tonic-gate ok( Film->can('db_Main'), 'set_db()' ); 248*0Sstevel@tonic-gate ok( $p->tests == 4, 'saw tests' ); 249*0Sstevel@tonic-gate ok( !grep !defined $_, @items, 'items populated' ); 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate(Mnemonic: "This is ok.") 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate$test_name is a very short description of the test that will be printed 254*0Sstevel@tonic-gateout. It makes it very easy to find a test in your script when it fails 255*0Sstevel@tonic-gateand gives others an idea of your intentions. $test_name is optional, 256*0Sstevel@tonic-gatebut we B<very> strongly encourage its use. 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gateShould an ok() fail, it will produce some diagnostics: 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate not ok 18 - sufficient mucus 261*0Sstevel@tonic-gate # Failed test 18 (foo.t at line 42) 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gateThis is actually Test::Simple's ok() routine. 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate=cut 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gatesub ok ($;$) { 268*0Sstevel@tonic-gate my($test, $name) = @_; 269*0Sstevel@tonic-gate $Test->ok($test, $name); 270*0Sstevel@tonic-gate} 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate=item B<is> 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate=item B<isnt> 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate is ( $this, $that, $test_name ); 277*0Sstevel@tonic-gate isnt( $this, $that, $test_name ); 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gateSimilar to ok(), is() and isnt() compare their two arguments 280*0Sstevel@tonic-gatewith C<eq> and C<ne> respectively and use the result of that to 281*0Sstevel@tonic-gatedetermine if the test succeeded or failed. So these: 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate # Is the ultimate answer 42? 284*0Sstevel@tonic-gate is( ultimate_answer(), 42, "Meaning of Life" ); 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate # $foo isn't empty 287*0Sstevel@tonic-gate isnt( $foo, '', "Got some foo" ); 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gateare similar to these: 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate ok( ultimate_answer() eq 42, "Meaning of Life" ); 292*0Sstevel@tonic-gate ok( $foo ne '', "Got some foo" ); 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate(Mnemonic: "This is that." "This isn't that.") 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gateSo why use these? They produce better diagnostics on failure. ok() 297*0Sstevel@tonic-gatecannot know what you are testing for (beyond the name), but is() and 298*0Sstevel@tonic-gateisnt() know what the test was and why it failed. For example this 299*0Sstevel@tonic-gatetest: 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate my $foo = 'waffle'; my $bar = 'yarblokos'; 302*0Sstevel@tonic-gate is( $foo, $bar, 'Is foo the same as bar?' ); 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gateWill produce something like this: 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate not ok 17 - Is foo the same as bar? 307*0Sstevel@tonic-gate # Failed test (foo.t at line 139) 308*0Sstevel@tonic-gate # got: 'waffle' 309*0Sstevel@tonic-gate # expected: 'yarblokos' 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gateSo you can figure out what went wrong without rerunning the test. 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gateYou are encouraged to use is() and isnt() over ok() where possible, 314*0Sstevel@tonic-gatehowever do not be tempted to use them to find out if something is 315*0Sstevel@tonic-gatetrue or false! 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate # XXX BAD! $pope->isa('Catholic') eq 1 318*0Sstevel@tonic-gate is( $pope->isa('Catholic'), 1, 'Is the Pope Catholic?' ); 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gateThis does not check if C<$pope->isa('Catholic')> is true, it checks if 321*0Sstevel@tonic-gateit returns 1. Very different. Similar caveats exist for false and 0. 322*0Sstevel@tonic-gateIn these cases, use ok(). 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate ok( $pope->isa('Catholic') ), 'Is the Pope Catholic?' ); 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gateFor those grammatical pedants out there, there's an C<isn't()> 327*0Sstevel@tonic-gatefunction which is an alias of isnt(). 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate=cut 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gatesub is ($$;$) { 332*0Sstevel@tonic-gate $Test->is_eq(@_); 333*0Sstevel@tonic-gate} 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gatesub isnt ($$;$) { 336*0Sstevel@tonic-gate $Test->isnt_eq(@_); 337*0Sstevel@tonic-gate} 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate*isn't = \&isnt; 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate 342*0Sstevel@tonic-gate=item B<like> 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate like( $this, qr/that/, $test_name ); 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gateSimilar to ok(), like() matches $this against the regex C<qr/that/>. 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gateSo this: 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate like($this, qr/that/, 'this is like that'); 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gateis similar to: 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate ok( $this =~ /that/, 'this is like that'); 355*0Sstevel@tonic-gate 356*0Sstevel@tonic-gate(Mnemonic "This is like that".) 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gateThe second argument is a regular expression. It may be given as a 359*0Sstevel@tonic-gateregex reference (i.e. C<qr//>) or (for better compatibility with older 360*0Sstevel@tonic-gateperls) as a string that looks like a regex (alternative delimiters are 361*0Sstevel@tonic-gatecurrently not supported): 362*0Sstevel@tonic-gate 363*0Sstevel@tonic-gate like( $this, '/that/', 'this is like that' ); 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gateRegex options may be placed on the end (C<'/that/i'>). 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gateIts advantages over ok() are similar to that of is() and isnt(). Better 368*0Sstevel@tonic-gatediagnostics on failure. 369*0Sstevel@tonic-gate 370*0Sstevel@tonic-gate=cut 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gatesub like ($$;$) { 373*0Sstevel@tonic-gate $Test->like(@_); 374*0Sstevel@tonic-gate} 375*0Sstevel@tonic-gate 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate=item B<unlike> 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate unlike( $this, qr/that/, $test_name ); 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gateWorks exactly as like(), only it checks if $this B<does not> match the 382*0Sstevel@tonic-gategiven pattern. 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gate=cut 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gatesub unlike { 387*0Sstevel@tonic-gate $Test->unlike(@_); 388*0Sstevel@tonic-gate} 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate=item B<cmp_ok> 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gate cmp_ok( $this, $op, $that, $test_name ); 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gateHalfway between ok() and is() lies cmp_ok(). This allows you to 396*0Sstevel@tonic-gatecompare two arguments using any binary perl operator. 397*0Sstevel@tonic-gate 398*0Sstevel@tonic-gate # ok( $this eq $that ); 399*0Sstevel@tonic-gate cmp_ok( $this, 'eq', $that, 'this eq that' ); 400*0Sstevel@tonic-gate 401*0Sstevel@tonic-gate # ok( $this == $that ); 402*0Sstevel@tonic-gate cmp_ok( $this, '==', $that, 'this == that' ); 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate # ok( $this && $that ); 405*0Sstevel@tonic-gate cmp_ok( $this, '&&', $that, 'this || that' ); 406*0Sstevel@tonic-gate ...etc... 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gateIts advantage over ok() is when the test fails you'll know what $this 409*0Sstevel@tonic-gateand $that were: 410*0Sstevel@tonic-gate 411*0Sstevel@tonic-gate not ok 1 412*0Sstevel@tonic-gate # Failed test (foo.t at line 12) 413*0Sstevel@tonic-gate # '23' 414*0Sstevel@tonic-gate # && 415*0Sstevel@tonic-gate # undef 416*0Sstevel@tonic-gate 417*0Sstevel@tonic-gateIt's also useful in those cases where you are comparing numbers and 418*0Sstevel@tonic-gateis()'s use of C<eq> will interfere: 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate cmp_ok( $big_hairy_number, '==', $another_big_hairy_number ); 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate=cut 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gatesub cmp_ok($$$;$) { 425*0Sstevel@tonic-gate $Test->cmp_ok(@_); 426*0Sstevel@tonic-gate} 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate 429*0Sstevel@tonic-gate=item B<can_ok> 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate can_ok($module, @methods); 432*0Sstevel@tonic-gate can_ok($object, @methods); 433*0Sstevel@tonic-gate 434*0Sstevel@tonic-gateChecks to make sure the $module or $object can do these @methods 435*0Sstevel@tonic-gate(works with functions, too). 436*0Sstevel@tonic-gate 437*0Sstevel@tonic-gate can_ok('Foo', qw(this that whatever)); 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gateis almost exactly like saying: 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate ok( Foo->can('this') && 442*0Sstevel@tonic-gate Foo->can('that') && 443*0Sstevel@tonic-gate Foo->can('whatever') 444*0Sstevel@tonic-gate ); 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gateonly without all the typing and with a better interface. Handy for 447*0Sstevel@tonic-gatequickly testing an interface. 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gateNo matter how many @methods you check, a single can_ok() call counts 450*0Sstevel@tonic-gateas one test. If you desire otherwise, use: 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate foreach my $meth (@methods) { 453*0Sstevel@tonic-gate can_ok('Foo', $meth); 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gate=cut 457*0Sstevel@tonic-gate 458*0Sstevel@tonic-gatesub can_ok ($@) { 459*0Sstevel@tonic-gate my($proto, @methods) = @_; 460*0Sstevel@tonic-gate my $class = ref $proto || $proto; 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate unless( @methods ) { 463*0Sstevel@tonic-gate my $ok = $Test->ok( 0, "$class->can(...)" ); 464*0Sstevel@tonic-gate $Test->diag(' can_ok() called with no methods'); 465*0Sstevel@tonic-gate return $ok; 466*0Sstevel@tonic-gate } 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate my @nok = (); 469*0Sstevel@tonic-gate foreach my $method (@methods) { 470*0Sstevel@tonic-gate local($!, $@); # don't interfere with caller's $@ 471*0Sstevel@tonic-gate # eval sometimes resets $! 472*0Sstevel@tonic-gate eval { $proto->can($method) } || push @nok, $method; 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate my $name; 476*0Sstevel@tonic-gate $name = @methods == 1 ? "$class->can('$methods[0]')" 477*0Sstevel@tonic-gate : "$class->can(...)"; 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate my $ok = $Test->ok( !@nok, $name ); 480*0Sstevel@tonic-gate 481*0Sstevel@tonic-gate $Test->diag(map " $class->can('$_') failed\n", @nok); 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate return $ok; 484*0Sstevel@tonic-gate} 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate=item B<isa_ok> 487*0Sstevel@tonic-gate 488*0Sstevel@tonic-gate isa_ok($object, $class, $object_name); 489*0Sstevel@tonic-gate isa_ok($ref, $type, $ref_name); 490*0Sstevel@tonic-gate 491*0Sstevel@tonic-gateChecks to see if the given $object->isa($class). Also checks to make 492*0Sstevel@tonic-gatesure the object was defined in the first place. Handy for this sort 493*0Sstevel@tonic-gateof thing: 494*0Sstevel@tonic-gate 495*0Sstevel@tonic-gate my $obj = Some::Module->new; 496*0Sstevel@tonic-gate isa_ok( $obj, 'Some::Module' ); 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gatewhere you'd otherwise have to write 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate my $obj = Some::Module->new; 501*0Sstevel@tonic-gate ok( defined $obj && $obj->isa('Some::Module') ); 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gateto safeguard against your test script blowing up. 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gateIt works on references, too: 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gate isa_ok( $array_ref, 'ARRAY' ); 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gateThe diagnostics of this test normally just refer to 'the object'. If 510*0Sstevel@tonic-gateyou'd like them to be more specific, you can supply an $object_name 511*0Sstevel@tonic-gate(for example 'Test customer'). 512*0Sstevel@tonic-gate 513*0Sstevel@tonic-gate=cut 514*0Sstevel@tonic-gate 515*0Sstevel@tonic-gatesub isa_ok ($$;$) { 516*0Sstevel@tonic-gate my($object, $class, $obj_name) = @_; 517*0Sstevel@tonic-gate 518*0Sstevel@tonic-gate my $diag; 519*0Sstevel@tonic-gate $obj_name = 'The object' unless defined $obj_name; 520*0Sstevel@tonic-gate my $name = "$obj_name isa $class"; 521*0Sstevel@tonic-gate if( !defined $object ) { 522*0Sstevel@tonic-gate $diag = "$obj_name isn't defined"; 523*0Sstevel@tonic-gate } 524*0Sstevel@tonic-gate elsif( !ref $object ) { 525*0Sstevel@tonic-gate $diag = "$obj_name isn't a reference"; 526*0Sstevel@tonic-gate } 527*0Sstevel@tonic-gate else { 528*0Sstevel@tonic-gate # We can't use UNIVERSAL::isa because we want to honor isa() overrides 529*0Sstevel@tonic-gate local($@, $!); # eval sometimes resets $! 530*0Sstevel@tonic-gate my $rslt = eval { $object->isa($class) }; 531*0Sstevel@tonic-gate if( $@ ) { 532*0Sstevel@tonic-gate if( $@ =~ /^Can't call method "isa" on unblessed reference/ ) { 533*0Sstevel@tonic-gate if( !UNIVERSAL::isa($object, $class) ) { 534*0Sstevel@tonic-gate my $ref = ref $object; 535*0Sstevel@tonic-gate $diag = "$obj_name isn't a '$class' it's a '$ref'"; 536*0Sstevel@tonic-gate } 537*0Sstevel@tonic-gate } else { 538*0Sstevel@tonic-gate die <<WHOA; 539*0Sstevel@tonic-gateWHOA! I tried to call ->isa on your object and got some weird error. 540*0Sstevel@tonic-gateThis should never happen. Please contact the author immediately. 541*0Sstevel@tonic-gateHere's the error. 542*0Sstevel@tonic-gate$@ 543*0Sstevel@tonic-gateWHOA 544*0Sstevel@tonic-gate } 545*0Sstevel@tonic-gate } 546*0Sstevel@tonic-gate elsif( !$rslt ) { 547*0Sstevel@tonic-gate my $ref = ref $object; 548*0Sstevel@tonic-gate $diag = "$obj_name isn't a '$class' it's a '$ref'"; 549*0Sstevel@tonic-gate } 550*0Sstevel@tonic-gate } 551*0Sstevel@tonic-gate 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gate 554*0Sstevel@tonic-gate my $ok; 555*0Sstevel@tonic-gate if( $diag ) { 556*0Sstevel@tonic-gate $ok = $Test->ok( 0, $name ); 557*0Sstevel@tonic-gate $Test->diag(" $diag\n"); 558*0Sstevel@tonic-gate } 559*0Sstevel@tonic-gate else { 560*0Sstevel@tonic-gate $ok = $Test->ok( 1, $name ); 561*0Sstevel@tonic-gate } 562*0Sstevel@tonic-gate 563*0Sstevel@tonic-gate return $ok; 564*0Sstevel@tonic-gate} 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate=item B<pass> 568*0Sstevel@tonic-gate 569*0Sstevel@tonic-gate=item B<fail> 570*0Sstevel@tonic-gate 571*0Sstevel@tonic-gate pass($test_name); 572*0Sstevel@tonic-gate fail($test_name); 573*0Sstevel@tonic-gate 574*0Sstevel@tonic-gateSometimes you just want to say that the tests have passed. Usually 575*0Sstevel@tonic-gatethe case is you've got some complicated condition that is difficult to 576*0Sstevel@tonic-gatewedge into an ok(). In this case, you can simply use pass() (to 577*0Sstevel@tonic-gatedeclare the test ok) or fail (for not ok). They are synonyms for 578*0Sstevel@tonic-gateok(1) and ok(0). 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gateUse these very, very, very sparingly. 581*0Sstevel@tonic-gate 582*0Sstevel@tonic-gate=cut 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gatesub pass (;$) { 585*0Sstevel@tonic-gate $Test->ok(1, @_); 586*0Sstevel@tonic-gate} 587*0Sstevel@tonic-gate 588*0Sstevel@tonic-gatesub fail (;$) { 589*0Sstevel@tonic-gate $Test->ok(0, @_); 590*0Sstevel@tonic-gate} 591*0Sstevel@tonic-gate 592*0Sstevel@tonic-gate=back 593*0Sstevel@tonic-gate 594*0Sstevel@tonic-gate=head2 Diagnostics 595*0Sstevel@tonic-gate 596*0Sstevel@tonic-gateIf you pick the right test function, you'll usually get a good idea of 597*0Sstevel@tonic-gatewhat went wrong when it failed. But sometimes it doesn't work out 598*0Sstevel@tonic-gatethat way. So here we have ways for you to write your own diagnostic 599*0Sstevel@tonic-gatemessages which are safer than just C<print STDERR>. 600*0Sstevel@tonic-gate 601*0Sstevel@tonic-gate=over 4 602*0Sstevel@tonic-gate 603*0Sstevel@tonic-gate=item B<diag> 604*0Sstevel@tonic-gate 605*0Sstevel@tonic-gate diag(@diagnostic_message); 606*0Sstevel@tonic-gate 607*0Sstevel@tonic-gatePrints a diagnostic message which is guaranteed not to interfere with 608*0Sstevel@tonic-gatetest output. Handy for this sort of thing: 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate ok( grep(/foo/, @users), "There's a foo user" ) or 611*0Sstevel@tonic-gate diag("Since there's no foo, check that /etc/bar is set up right"); 612*0Sstevel@tonic-gate 613*0Sstevel@tonic-gatewhich would produce: 614*0Sstevel@tonic-gate 615*0Sstevel@tonic-gate not ok 42 - There's a foo user 616*0Sstevel@tonic-gate # Failed test (foo.t at line 52) 617*0Sstevel@tonic-gate # Since there's no foo, check that /etc/bar is set up right. 618*0Sstevel@tonic-gate 619*0Sstevel@tonic-gateYou might remember C<ok() or diag()> with the mnemonic C<open() or 620*0Sstevel@tonic-gatedie()>. 621*0Sstevel@tonic-gate 622*0Sstevel@tonic-gateB<NOTE> The exact formatting of the diagnostic output is still 623*0Sstevel@tonic-gatechanging, but it is guaranteed that whatever you throw at it it won't 624*0Sstevel@tonic-gateinterfere with the test. 625*0Sstevel@tonic-gate 626*0Sstevel@tonic-gate=cut 627*0Sstevel@tonic-gate 628*0Sstevel@tonic-gatesub diag { 629*0Sstevel@tonic-gate $Test->diag(@_); 630*0Sstevel@tonic-gate} 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate 633*0Sstevel@tonic-gate=back 634*0Sstevel@tonic-gate 635*0Sstevel@tonic-gate=head2 Module tests 636*0Sstevel@tonic-gate 637*0Sstevel@tonic-gateYou usually want to test if the module you're testing loads ok, rather 638*0Sstevel@tonic-gatethan just vomiting if its load fails. For such purposes we have 639*0Sstevel@tonic-gateC<use_ok> and C<require_ok>. 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gate=over 4 642*0Sstevel@tonic-gate 643*0Sstevel@tonic-gate=item B<use_ok> 644*0Sstevel@tonic-gate 645*0Sstevel@tonic-gate BEGIN { use_ok($module); } 646*0Sstevel@tonic-gate BEGIN { use_ok($module, @imports); } 647*0Sstevel@tonic-gate 648*0Sstevel@tonic-gateThese simply use the given $module and test to make sure the load 649*0Sstevel@tonic-gatehappened ok. It's recommended that you run use_ok() inside a BEGIN 650*0Sstevel@tonic-gateblock so its functions are exported at compile-time and prototypes are 651*0Sstevel@tonic-gateproperly honored. 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gateIf @imports are given, they are passed through to the use. So this: 654*0Sstevel@tonic-gate 655*0Sstevel@tonic-gate BEGIN { use_ok('Some::Module', qw(foo bar)) } 656*0Sstevel@tonic-gate 657*0Sstevel@tonic-gateis like doing this: 658*0Sstevel@tonic-gate 659*0Sstevel@tonic-gate use Some::Module qw(foo bar); 660*0Sstevel@tonic-gate 661*0Sstevel@tonic-gatedon't try to do this: 662*0Sstevel@tonic-gate 663*0Sstevel@tonic-gate BEGIN { 664*0Sstevel@tonic-gate use_ok('Some::Module'); 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate ...some code that depends on the use... 667*0Sstevel@tonic-gate ...happening at compile time... 668*0Sstevel@tonic-gate } 669*0Sstevel@tonic-gate 670*0Sstevel@tonic-gateinstead, you want: 671*0Sstevel@tonic-gate 672*0Sstevel@tonic-gate BEGIN { use_ok('Some::Module') } 673*0Sstevel@tonic-gate BEGIN { ...some code that depends on the use... } 674*0Sstevel@tonic-gate 675*0Sstevel@tonic-gate 676*0Sstevel@tonic-gate=cut 677*0Sstevel@tonic-gate 678*0Sstevel@tonic-gatesub use_ok ($;@) { 679*0Sstevel@tonic-gate my($module, @imports) = @_; 680*0Sstevel@tonic-gate @imports = () unless @imports; 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate my $pack = caller; 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate local($@,$!); # eval sometimes interferes with $! 685*0Sstevel@tonic-gate eval <<USE; 686*0Sstevel@tonic-gatepackage $pack; 687*0Sstevel@tonic-gaterequire $module; 688*0Sstevel@tonic-gate'$module'->import(\@imports); 689*0Sstevel@tonic-gateUSE 690*0Sstevel@tonic-gate 691*0Sstevel@tonic-gate my $ok = $Test->ok( !$@, "use $module;" ); 692*0Sstevel@tonic-gate 693*0Sstevel@tonic-gate unless( $ok ) { 694*0Sstevel@tonic-gate chomp $@; 695*0Sstevel@tonic-gate $Test->diag(<<DIAGNOSTIC); 696*0Sstevel@tonic-gate Tried to use '$module'. 697*0Sstevel@tonic-gate Error: $@ 698*0Sstevel@tonic-gateDIAGNOSTIC 699*0Sstevel@tonic-gate 700*0Sstevel@tonic-gate } 701*0Sstevel@tonic-gate 702*0Sstevel@tonic-gate return $ok; 703*0Sstevel@tonic-gate} 704*0Sstevel@tonic-gate 705*0Sstevel@tonic-gate=item B<require_ok> 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate require_ok($module); 708*0Sstevel@tonic-gate 709*0Sstevel@tonic-gateLike use_ok(), except it requires the $module. 710*0Sstevel@tonic-gate 711*0Sstevel@tonic-gate=cut 712*0Sstevel@tonic-gate 713*0Sstevel@tonic-gatesub require_ok ($) { 714*0Sstevel@tonic-gate my($module) = shift; 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gate my $pack = caller; 717*0Sstevel@tonic-gate 718*0Sstevel@tonic-gate local($!, $@); # eval sometimes interferes with $! 719*0Sstevel@tonic-gate eval <<REQUIRE; 720*0Sstevel@tonic-gatepackage $pack; 721*0Sstevel@tonic-gaterequire $module; 722*0Sstevel@tonic-gateREQUIRE 723*0Sstevel@tonic-gate 724*0Sstevel@tonic-gate my $ok = $Test->ok( !$@, "require $module;" ); 725*0Sstevel@tonic-gate 726*0Sstevel@tonic-gate unless( $ok ) { 727*0Sstevel@tonic-gate chomp $@; 728*0Sstevel@tonic-gate $Test->diag(<<DIAGNOSTIC); 729*0Sstevel@tonic-gate Tried to require '$module'. 730*0Sstevel@tonic-gate Error: $@ 731*0Sstevel@tonic-gateDIAGNOSTIC 732*0Sstevel@tonic-gate 733*0Sstevel@tonic-gate } 734*0Sstevel@tonic-gate 735*0Sstevel@tonic-gate return $ok; 736*0Sstevel@tonic-gate} 737*0Sstevel@tonic-gate 738*0Sstevel@tonic-gate=back 739*0Sstevel@tonic-gate 740*0Sstevel@tonic-gate=head2 Conditional tests 741*0Sstevel@tonic-gate 742*0Sstevel@tonic-gateSometimes running a test under certain conditions will cause the 743*0Sstevel@tonic-gatetest script to die. A certain function or method isn't implemented 744*0Sstevel@tonic-gate(such as fork() on MacOS), some resource isn't available (like a 745*0Sstevel@tonic-gatenet connection) or a module isn't available. In these cases it's 746*0Sstevel@tonic-gatenecessary to skip tests, or declare that they are supposed to fail 747*0Sstevel@tonic-gatebut will work in the future (a todo test). 748*0Sstevel@tonic-gate 749*0Sstevel@tonic-gateFor more details on the mechanics of skip and todo tests see 750*0Sstevel@tonic-gateL<Test::Harness>. 751*0Sstevel@tonic-gate 752*0Sstevel@tonic-gateThe way Test::More handles this is with a named block. Basically, a 753*0Sstevel@tonic-gateblock of tests which can be skipped over or made todo. It's best if I 754*0Sstevel@tonic-gatejust show you... 755*0Sstevel@tonic-gate 756*0Sstevel@tonic-gate=over 4 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate=item B<SKIP: BLOCK> 759*0Sstevel@tonic-gate 760*0Sstevel@tonic-gate SKIP: { 761*0Sstevel@tonic-gate skip $why, $how_many if $condition; 762*0Sstevel@tonic-gate 763*0Sstevel@tonic-gate ...normal testing code goes here... 764*0Sstevel@tonic-gate } 765*0Sstevel@tonic-gate 766*0Sstevel@tonic-gateThis declares a block of tests that might be skipped, $how_many tests 767*0Sstevel@tonic-gatethere are, $why and under what $condition to skip them. An example is 768*0Sstevel@tonic-gatethe easiest way to illustrate: 769*0Sstevel@tonic-gate 770*0Sstevel@tonic-gate SKIP: { 771*0Sstevel@tonic-gate eval { require HTML::Lint }; 772*0Sstevel@tonic-gate 773*0Sstevel@tonic-gate skip "HTML::Lint not installed", 2 if $@; 774*0Sstevel@tonic-gate 775*0Sstevel@tonic-gate my $lint = new HTML::Lint; 776*0Sstevel@tonic-gate isa_ok( $lint, "HTML::Lint" ); 777*0Sstevel@tonic-gate 778*0Sstevel@tonic-gate $lint->parse( $html ); 779*0Sstevel@tonic-gate is( $lint->errors, 0, "No errors found in HTML" ); 780*0Sstevel@tonic-gate } 781*0Sstevel@tonic-gate 782*0Sstevel@tonic-gateIf the user does not have HTML::Lint installed, the whole block of 783*0Sstevel@tonic-gatecode I<won't be run at all>. Test::More will output special ok's 784*0Sstevel@tonic-gatewhich Test::Harness interprets as skipped, but passing, tests. 785*0Sstevel@tonic-gateIt's important that $how_many accurately reflects the number of tests 786*0Sstevel@tonic-gatein the SKIP block so the # of tests run will match up with your plan. 787*0Sstevel@tonic-gate 788*0Sstevel@tonic-gateIt's perfectly safe to nest SKIP blocks. Each SKIP block must have 789*0Sstevel@tonic-gatethe label C<SKIP>, or Test::More can't work its magic. 790*0Sstevel@tonic-gate 791*0Sstevel@tonic-gateYou don't skip tests which are failing because there's a bug in your 792*0Sstevel@tonic-gateprogram, or for which you don't yet have code written. For that you 793*0Sstevel@tonic-gateuse TODO. Read on. 794*0Sstevel@tonic-gate 795*0Sstevel@tonic-gate=cut 796*0Sstevel@tonic-gate 797*0Sstevel@tonic-gate#'# 798*0Sstevel@tonic-gatesub skip { 799*0Sstevel@tonic-gate my($why, $how_many) = @_; 800*0Sstevel@tonic-gate 801*0Sstevel@tonic-gate unless( defined $how_many ) { 802*0Sstevel@tonic-gate # $how_many can only be avoided when no_plan is in use. 803*0Sstevel@tonic-gate _carp "skip() needs to know \$how_many tests are in the block" 804*0Sstevel@tonic-gate unless $Test::Builder::No_Plan; 805*0Sstevel@tonic-gate $how_many = 1; 806*0Sstevel@tonic-gate } 807*0Sstevel@tonic-gate 808*0Sstevel@tonic-gate for( 1..$how_many ) { 809*0Sstevel@tonic-gate $Test->skip($why); 810*0Sstevel@tonic-gate } 811*0Sstevel@tonic-gate 812*0Sstevel@tonic-gate local $^W = 0; 813*0Sstevel@tonic-gate last SKIP; 814*0Sstevel@tonic-gate} 815*0Sstevel@tonic-gate 816*0Sstevel@tonic-gate 817*0Sstevel@tonic-gate=item B<TODO: BLOCK> 818*0Sstevel@tonic-gate 819*0Sstevel@tonic-gate TODO: { 820*0Sstevel@tonic-gate local $TODO = $why if $condition; 821*0Sstevel@tonic-gate 822*0Sstevel@tonic-gate ...normal testing code goes here... 823*0Sstevel@tonic-gate } 824*0Sstevel@tonic-gate 825*0Sstevel@tonic-gateDeclares a block of tests you expect to fail and $why. Perhaps it's 826*0Sstevel@tonic-gatebecause you haven't fixed a bug or haven't finished a new feature: 827*0Sstevel@tonic-gate 828*0Sstevel@tonic-gate TODO: { 829*0Sstevel@tonic-gate local $TODO = "URI::Geller not finished"; 830*0Sstevel@tonic-gate 831*0Sstevel@tonic-gate my $card = "Eight of clubs"; 832*0Sstevel@tonic-gate is( URI::Geller->your_card, $card, 'Is THIS your card?' ); 833*0Sstevel@tonic-gate 834*0Sstevel@tonic-gate my $spoon; 835*0Sstevel@tonic-gate URI::Geller->bend_spoon; 836*0Sstevel@tonic-gate is( $spoon, 'bent', "Spoon bending, that's original" ); 837*0Sstevel@tonic-gate } 838*0Sstevel@tonic-gate 839*0Sstevel@tonic-gateWith a todo block, the tests inside are expected to fail. Test::More 840*0Sstevel@tonic-gatewill run the tests normally, but print out special flags indicating 841*0Sstevel@tonic-gatethey are "todo". Test::Harness will interpret failures as being ok. 842*0Sstevel@tonic-gateShould anything succeed, it will report it as an unexpected success. 843*0Sstevel@tonic-gateYou then know the thing you had todo is done and can remove the 844*0Sstevel@tonic-gateTODO flag. 845*0Sstevel@tonic-gate 846*0Sstevel@tonic-gateThe nice part about todo tests, as opposed to simply commenting out a 847*0Sstevel@tonic-gateblock of tests, is it's like having a programmatic todo list. You know 848*0Sstevel@tonic-gatehow much work is left to be done, you're aware of what bugs there are, 849*0Sstevel@tonic-gateand you'll know immediately when they're fixed. 850*0Sstevel@tonic-gate 851*0Sstevel@tonic-gateOnce a todo test starts succeeding, simply move it outside the block. 852*0Sstevel@tonic-gateWhen the block is empty, delete it. 853*0Sstevel@tonic-gate 854*0Sstevel@tonic-gate 855*0Sstevel@tonic-gate=item B<todo_skip> 856*0Sstevel@tonic-gate 857*0Sstevel@tonic-gate TODO: { 858*0Sstevel@tonic-gate todo_skip $why, $how_many if $condition; 859*0Sstevel@tonic-gate 860*0Sstevel@tonic-gate ...normal testing code... 861*0Sstevel@tonic-gate } 862*0Sstevel@tonic-gate 863*0Sstevel@tonic-gateWith todo tests, it's best to have the tests actually run. That way 864*0Sstevel@tonic-gateyou'll know when they start passing. Sometimes this isn't possible. 865*0Sstevel@tonic-gateOften a failing test will cause the whole program to die or hang, even 866*0Sstevel@tonic-gateinside an C<eval BLOCK> with and using C<alarm>. In these extreme 867*0Sstevel@tonic-gatecases you have no choice but to skip over the broken tests entirely. 868*0Sstevel@tonic-gate 869*0Sstevel@tonic-gateThe syntax and behavior is similar to a C<SKIP: BLOCK> except the 870*0Sstevel@tonic-gatetests will be marked as failing but todo. Test::Harness will 871*0Sstevel@tonic-gateinterpret them as passing. 872*0Sstevel@tonic-gate 873*0Sstevel@tonic-gate=cut 874*0Sstevel@tonic-gate 875*0Sstevel@tonic-gatesub todo_skip { 876*0Sstevel@tonic-gate my($why, $how_many) = @_; 877*0Sstevel@tonic-gate 878*0Sstevel@tonic-gate unless( defined $how_many ) { 879*0Sstevel@tonic-gate # $how_many can only be avoided when no_plan is in use. 880*0Sstevel@tonic-gate _carp "todo_skip() needs to know \$how_many tests are in the block" 881*0Sstevel@tonic-gate unless $Test::Builder::No_Plan; 882*0Sstevel@tonic-gate $how_many = 1; 883*0Sstevel@tonic-gate } 884*0Sstevel@tonic-gate 885*0Sstevel@tonic-gate for( 1..$how_many ) { 886*0Sstevel@tonic-gate $Test->todo_skip($why); 887*0Sstevel@tonic-gate } 888*0Sstevel@tonic-gate 889*0Sstevel@tonic-gate local $^W = 0; 890*0Sstevel@tonic-gate last TODO; 891*0Sstevel@tonic-gate} 892*0Sstevel@tonic-gate 893*0Sstevel@tonic-gate=item When do I use SKIP vs. TODO? 894*0Sstevel@tonic-gate 895*0Sstevel@tonic-gateB<If it's something the user might not be able to do>, use SKIP. 896*0Sstevel@tonic-gateThis includes optional modules that aren't installed, running under 897*0Sstevel@tonic-gatean OS that doesn't have some feature (like fork() or symlinks), or maybe 898*0Sstevel@tonic-gateyou need an Internet connection and one isn't available. 899*0Sstevel@tonic-gate 900*0Sstevel@tonic-gateB<If it's something the programmer hasn't done yet>, use TODO. This 901*0Sstevel@tonic-gateis for any code you haven't written yet, or bugs you have yet to fix, 902*0Sstevel@tonic-gatebut want to put tests in your testing script (always a good idea). 903*0Sstevel@tonic-gate 904*0Sstevel@tonic-gate 905*0Sstevel@tonic-gate=back 906*0Sstevel@tonic-gate 907*0Sstevel@tonic-gate=head2 Comparison functions 908*0Sstevel@tonic-gate 909*0Sstevel@tonic-gateNot everything is a simple eq check or regex. There are times you 910*0Sstevel@tonic-gateneed to see if two arrays are equivalent, for instance. For these 911*0Sstevel@tonic-gateinstances, Test::More provides a handful of useful functions. 912*0Sstevel@tonic-gate 913*0Sstevel@tonic-gateB<NOTE> These are NOT well-tested on circular references. Nor am I 914*0Sstevel@tonic-gatequite sure what will happen with filehandles. 915*0Sstevel@tonic-gate 916*0Sstevel@tonic-gate=over 4 917*0Sstevel@tonic-gate 918*0Sstevel@tonic-gate=item B<is_deeply> 919*0Sstevel@tonic-gate 920*0Sstevel@tonic-gate is_deeply( $this, $that, $test_name ); 921*0Sstevel@tonic-gate 922*0Sstevel@tonic-gateSimilar to is(), except that if $this and $that are hash or array 923*0Sstevel@tonic-gatereferences, it does a deep comparison walking each data structure to 924*0Sstevel@tonic-gatesee if they are equivalent. If the two structures are different, it 925*0Sstevel@tonic-gatewill display the place where they start differing. 926*0Sstevel@tonic-gate 927*0Sstevel@tonic-gateBarrie Slaymaker's Test::Differences module provides more in-depth 928*0Sstevel@tonic-gatefunctionality along these lines, and it plays well with Test::More. 929*0Sstevel@tonic-gate 930*0Sstevel@tonic-gateB<NOTE> Display of scalar refs is not quite 100% 931*0Sstevel@tonic-gate 932*0Sstevel@tonic-gate=cut 933*0Sstevel@tonic-gate 934*0Sstevel@tonic-gateuse vars qw(@Data_Stack); 935*0Sstevel@tonic-gatemy $DNE = bless [], 'Does::Not::Exist'; 936*0Sstevel@tonic-gatesub is_deeply { 937*0Sstevel@tonic-gate my($this, $that, $name) = @_; 938*0Sstevel@tonic-gate 939*0Sstevel@tonic-gate my $ok; 940*0Sstevel@tonic-gate if( !ref $this || !ref $that ) { 941*0Sstevel@tonic-gate $ok = $Test->is_eq($this, $that, $name); 942*0Sstevel@tonic-gate } 943*0Sstevel@tonic-gate else { 944*0Sstevel@tonic-gate local @Data_Stack = (); 945*0Sstevel@tonic-gate if( _deep_check($this, $that) ) { 946*0Sstevel@tonic-gate $ok = $Test->ok(1, $name); 947*0Sstevel@tonic-gate } 948*0Sstevel@tonic-gate else { 949*0Sstevel@tonic-gate $ok = $Test->ok(0, $name); 950*0Sstevel@tonic-gate $ok = $Test->diag(_format_stack(@Data_Stack)); 951*0Sstevel@tonic-gate } 952*0Sstevel@tonic-gate } 953*0Sstevel@tonic-gate 954*0Sstevel@tonic-gate return $ok; 955*0Sstevel@tonic-gate} 956*0Sstevel@tonic-gate 957*0Sstevel@tonic-gatesub _format_stack { 958*0Sstevel@tonic-gate my(@Stack) = @_; 959*0Sstevel@tonic-gate 960*0Sstevel@tonic-gate my $var = '$FOO'; 961*0Sstevel@tonic-gate my $did_arrow = 0; 962*0Sstevel@tonic-gate foreach my $entry (@Stack) { 963*0Sstevel@tonic-gate my $type = $entry->{type} || ''; 964*0Sstevel@tonic-gate my $idx = $entry->{'idx'}; 965*0Sstevel@tonic-gate if( $type eq 'HASH' ) { 966*0Sstevel@tonic-gate $var .= "->" unless $did_arrow++; 967*0Sstevel@tonic-gate $var .= "{$idx}"; 968*0Sstevel@tonic-gate } 969*0Sstevel@tonic-gate elsif( $type eq 'ARRAY' ) { 970*0Sstevel@tonic-gate $var .= "->" unless $did_arrow++; 971*0Sstevel@tonic-gate $var .= "[$idx]"; 972*0Sstevel@tonic-gate } 973*0Sstevel@tonic-gate elsif( $type eq 'REF' ) { 974*0Sstevel@tonic-gate $var = "\${$var}"; 975*0Sstevel@tonic-gate } 976*0Sstevel@tonic-gate } 977*0Sstevel@tonic-gate 978*0Sstevel@tonic-gate my @vals = @{$Stack[-1]{vals}}[0,1]; 979*0Sstevel@tonic-gate my @vars = (); 980*0Sstevel@tonic-gate ($vars[0] = $var) =~ s/\$FOO/ \$got/; 981*0Sstevel@tonic-gate ($vars[1] = $var) =~ s/\$FOO/\$expected/; 982*0Sstevel@tonic-gate 983*0Sstevel@tonic-gate my $out = "Structures begin differing at:\n"; 984*0Sstevel@tonic-gate foreach my $idx (0..$#vals) { 985*0Sstevel@tonic-gate my $val = $vals[$idx]; 986*0Sstevel@tonic-gate $vals[$idx] = !defined $val ? 'undef' : 987*0Sstevel@tonic-gate $val eq $DNE ? "Does not exist" 988*0Sstevel@tonic-gate : "'$val'"; 989*0Sstevel@tonic-gate } 990*0Sstevel@tonic-gate 991*0Sstevel@tonic-gate $out .= "$vars[0] = $vals[0]\n"; 992*0Sstevel@tonic-gate $out .= "$vars[1] = $vals[1]\n"; 993*0Sstevel@tonic-gate 994*0Sstevel@tonic-gate $out =~ s/^/ /msg; 995*0Sstevel@tonic-gate return $out; 996*0Sstevel@tonic-gate} 997*0Sstevel@tonic-gate 998*0Sstevel@tonic-gate 999*0Sstevel@tonic-gate=item B<eq_array> 1000*0Sstevel@tonic-gate 1001*0Sstevel@tonic-gate eq_array(\@this, \@that); 1002*0Sstevel@tonic-gate 1003*0Sstevel@tonic-gateChecks if two arrays are equivalent. This is a deep check, so 1004*0Sstevel@tonic-gatemulti-level structures are handled correctly. 1005*0Sstevel@tonic-gate 1006*0Sstevel@tonic-gate=cut 1007*0Sstevel@tonic-gate 1008*0Sstevel@tonic-gate#'# 1009*0Sstevel@tonic-gatesub eq_array { 1010*0Sstevel@tonic-gate my($a1, $a2) = @_; 1011*0Sstevel@tonic-gate return 1 if $a1 eq $a2; 1012*0Sstevel@tonic-gate 1013*0Sstevel@tonic-gate my $ok = 1; 1014*0Sstevel@tonic-gate my $max = $#$a1 > $#$a2 ? $#$a1 : $#$a2; 1015*0Sstevel@tonic-gate for (0..$max) { 1016*0Sstevel@tonic-gate my $e1 = $_ > $#$a1 ? $DNE : $a1->[$_]; 1017*0Sstevel@tonic-gate my $e2 = $_ > $#$a2 ? $DNE : $a2->[$_]; 1018*0Sstevel@tonic-gate 1019*0Sstevel@tonic-gate push @Data_Stack, { type => 'ARRAY', idx => $_, vals => [$e1, $e2] }; 1020*0Sstevel@tonic-gate $ok = _deep_check($e1,$e2); 1021*0Sstevel@tonic-gate pop @Data_Stack if $ok; 1022*0Sstevel@tonic-gate 1023*0Sstevel@tonic-gate last unless $ok; 1024*0Sstevel@tonic-gate } 1025*0Sstevel@tonic-gate return $ok; 1026*0Sstevel@tonic-gate} 1027*0Sstevel@tonic-gate 1028*0Sstevel@tonic-gatesub _deep_check { 1029*0Sstevel@tonic-gate my($e1, $e2) = @_; 1030*0Sstevel@tonic-gate my $ok = 0; 1031*0Sstevel@tonic-gate 1032*0Sstevel@tonic-gate my $eq; 1033*0Sstevel@tonic-gate { 1034*0Sstevel@tonic-gate # Quiet uninitialized value warnings when comparing undefs. 1035*0Sstevel@tonic-gate local $^W = 0; 1036*0Sstevel@tonic-gate 1037*0Sstevel@tonic-gate if( $e1 eq $e2 ) { 1038*0Sstevel@tonic-gate $ok = 1; 1039*0Sstevel@tonic-gate } 1040*0Sstevel@tonic-gate else { 1041*0Sstevel@tonic-gate if( UNIVERSAL::isa($e1, 'ARRAY') and 1042*0Sstevel@tonic-gate UNIVERSAL::isa($e2, 'ARRAY') ) 1043*0Sstevel@tonic-gate { 1044*0Sstevel@tonic-gate $ok = eq_array($e1, $e2); 1045*0Sstevel@tonic-gate } 1046*0Sstevel@tonic-gate elsif( UNIVERSAL::isa($e1, 'HASH') and 1047*0Sstevel@tonic-gate UNIVERSAL::isa($e2, 'HASH') ) 1048*0Sstevel@tonic-gate { 1049*0Sstevel@tonic-gate $ok = eq_hash($e1, $e2); 1050*0Sstevel@tonic-gate } 1051*0Sstevel@tonic-gate elsif( UNIVERSAL::isa($e1, 'REF') and 1052*0Sstevel@tonic-gate UNIVERSAL::isa($e2, 'REF') ) 1053*0Sstevel@tonic-gate { 1054*0Sstevel@tonic-gate push @Data_Stack, { type => 'REF', vals => [$e1, $e2] }; 1055*0Sstevel@tonic-gate $ok = _deep_check($$e1, $$e2); 1056*0Sstevel@tonic-gate pop @Data_Stack if $ok; 1057*0Sstevel@tonic-gate } 1058*0Sstevel@tonic-gate elsif( UNIVERSAL::isa($e1, 'SCALAR') and 1059*0Sstevel@tonic-gate UNIVERSAL::isa($e2, 'SCALAR') ) 1060*0Sstevel@tonic-gate { 1061*0Sstevel@tonic-gate push @Data_Stack, { type => 'REF', vals => [$e1, $e2] }; 1062*0Sstevel@tonic-gate $ok = _deep_check($$e1, $$e2); 1063*0Sstevel@tonic-gate } 1064*0Sstevel@tonic-gate else { 1065*0Sstevel@tonic-gate push @Data_Stack, { vals => [$e1, $e2] }; 1066*0Sstevel@tonic-gate $ok = 0; 1067*0Sstevel@tonic-gate } 1068*0Sstevel@tonic-gate } 1069*0Sstevel@tonic-gate } 1070*0Sstevel@tonic-gate 1071*0Sstevel@tonic-gate return $ok; 1072*0Sstevel@tonic-gate} 1073*0Sstevel@tonic-gate 1074*0Sstevel@tonic-gate 1075*0Sstevel@tonic-gate=item B<eq_hash> 1076*0Sstevel@tonic-gate 1077*0Sstevel@tonic-gate eq_hash(\%this, \%that); 1078*0Sstevel@tonic-gate 1079*0Sstevel@tonic-gateDetermines if the two hashes contain the same keys and values. This 1080*0Sstevel@tonic-gateis a deep check. 1081*0Sstevel@tonic-gate 1082*0Sstevel@tonic-gate=cut 1083*0Sstevel@tonic-gate 1084*0Sstevel@tonic-gatesub eq_hash { 1085*0Sstevel@tonic-gate my($a1, $a2) = @_; 1086*0Sstevel@tonic-gate return 1 if $a1 eq $a2; 1087*0Sstevel@tonic-gate 1088*0Sstevel@tonic-gate my $ok = 1; 1089*0Sstevel@tonic-gate my $bigger = keys %$a1 > keys %$a2 ? $a1 : $a2; 1090*0Sstevel@tonic-gate foreach my $k (keys %$bigger) { 1091*0Sstevel@tonic-gate my $e1 = exists $a1->{$k} ? $a1->{$k} : $DNE; 1092*0Sstevel@tonic-gate my $e2 = exists $a2->{$k} ? $a2->{$k} : $DNE; 1093*0Sstevel@tonic-gate 1094*0Sstevel@tonic-gate push @Data_Stack, { type => 'HASH', idx => $k, vals => [$e1, $e2] }; 1095*0Sstevel@tonic-gate $ok = _deep_check($e1, $e2); 1096*0Sstevel@tonic-gate pop @Data_Stack if $ok; 1097*0Sstevel@tonic-gate 1098*0Sstevel@tonic-gate last unless $ok; 1099*0Sstevel@tonic-gate } 1100*0Sstevel@tonic-gate 1101*0Sstevel@tonic-gate return $ok; 1102*0Sstevel@tonic-gate} 1103*0Sstevel@tonic-gate 1104*0Sstevel@tonic-gate=item B<eq_set> 1105*0Sstevel@tonic-gate 1106*0Sstevel@tonic-gate eq_set(\@this, \@that); 1107*0Sstevel@tonic-gate 1108*0Sstevel@tonic-gateSimilar to eq_array(), except the order of the elements is B<not> 1109*0Sstevel@tonic-gateimportant. This is a deep check, but the irrelevancy of order only 1110*0Sstevel@tonic-gateapplies to the top level. 1111*0Sstevel@tonic-gate 1112*0Sstevel@tonic-gateB<NOTE> By historical accident, this is not a true set comparision. 1113*0Sstevel@tonic-gateWhile the order of elements does not matter, duplicate elements do. 1114*0Sstevel@tonic-gate 1115*0Sstevel@tonic-gate=cut 1116*0Sstevel@tonic-gate 1117*0Sstevel@tonic-gate# We must make sure that references are treated neutrally. It really 1118*0Sstevel@tonic-gate# doesn't matter how we sort them, as long as both arrays are sorted 1119*0Sstevel@tonic-gate# with the same algorithm. 1120*0Sstevel@tonic-gatesub _bogus_sort { local $^W = 0; ref $a ? 0 : $a cmp $b } 1121*0Sstevel@tonic-gate 1122*0Sstevel@tonic-gatesub eq_set { 1123*0Sstevel@tonic-gate my($a1, $a2) = @_; 1124*0Sstevel@tonic-gate return 0 unless @$a1 == @$a2; 1125*0Sstevel@tonic-gate 1126*0Sstevel@tonic-gate # There's faster ways to do this, but this is easiest. 1127*0Sstevel@tonic-gate return eq_array( [sort _bogus_sort @$a1], [sort _bogus_sort @$a2] ); 1128*0Sstevel@tonic-gate} 1129*0Sstevel@tonic-gate 1130*0Sstevel@tonic-gate=back 1131*0Sstevel@tonic-gate 1132*0Sstevel@tonic-gate 1133*0Sstevel@tonic-gate=head2 Extending and Embedding Test::More 1134*0Sstevel@tonic-gate 1135*0Sstevel@tonic-gateSometimes the Test::More interface isn't quite enough. Fortunately, 1136*0Sstevel@tonic-gateTest::More is built on top of Test::Builder which provides a single, 1137*0Sstevel@tonic-gateunified backend for any test library to use. This means two test 1138*0Sstevel@tonic-gatelibraries which both use Test::Builder B<can be used together in the 1139*0Sstevel@tonic-gatesame program>. 1140*0Sstevel@tonic-gate 1141*0Sstevel@tonic-gateIf you simply want to do a little tweaking of how the tests behave, 1142*0Sstevel@tonic-gateyou can access the underlying Test::Builder object like so: 1143*0Sstevel@tonic-gate 1144*0Sstevel@tonic-gate=over 4 1145*0Sstevel@tonic-gate 1146*0Sstevel@tonic-gate=item B<builder> 1147*0Sstevel@tonic-gate 1148*0Sstevel@tonic-gate my $test_builder = Test::More->builder; 1149*0Sstevel@tonic-gate 1150*0Sstevel@tonic-gateReturns the Test::Builder object underlying Test::More for you to play 1151*0Sstevel@tonic-gatewith. 1152*0Sstevel@tonic-gate 1153*0Sstevel@tonic-gate=cut 1154*0Sstevel@tonic-gate 1155*0Sstevel@tonic-gatesub builder { 1156*0Sstevel@tonic-gate return Test::Builder->new; 1157*0Sstevel@tonic-gate} 1158*0Sstevel@tonic-gate 1159*0Sstevel@tonic-gate=back 1160*0Sstevel@tonic-gate 1161*0Sstevel@tonic-gate 1162*0Sstevel@tonic-gate=head1 NOTES 1163*0Sstevel@tonic-gate 1164*0Sstevel@tonic-gateTest::More is B<explicitly> tested all the way back to perl 5.004. 1165*0Sstevel@tonic-gate 1166*0Sstevel@tonic-gateTest::More is thread-safe for perl 5.8.0 and up. 1167*0Sstevel@tonic-gate 1168*0Sstevel@tonic-gate=head1 BUGS and CAVEATS 1169*0Sstevel@tonic-gate 1170*0Sstevel@tonic-gate=over 4 1171*0Sstevel@tonic-gate 1172*0Sstevel@tonic-gate=item Making your own ok() 1173*0Sstevel@tonic-gate 1174*0Sstevel@tonic-gateIf you are trying to extend Test::More, don't. Use Test::Builder 1175*0Sstevel@tonic-gateinstead. 1176*0Sstevel@tonic-gate 1177*0Sstevel@tonic-gate=item The eq_* family has some caveats. 1178*0Sstevel@tonic-gate 1179*0Sstevel@tonic-gate=item Test::Harness upgrades 1180*0Sstevel@tonic-gate 1181*0Sstevel@tonic-gateno_plan and todo depend on new Test::Harness features and fixes. If 1182*0Sstevel@tonic-gateyou're going to distribute tests that use no_plan or todo your 1183*0Sstevel@tonic-gateend-users will have to upgrade Test::Harness to the latest one on 1184*0Sstevel@tonic-gateCPAN. If you avoid no_plan and TODO tests, the stock Test::Harness 1185*0Sstevel@tonic-gatewill work fine. 1186*0Sstevel@tonic-gate 1187*0Sstevel@tonic-gateIf you simply depend on Test::More, it's own dependencies will cause a 1188*0Sstevel@tonic-gateTest::Harness upgrade. 1189*0Sstevel@tonic-gate 1190*0Sstevel@tonic-gate=back 1191*0Sstevel@tonic-gate 1192*0Sstevel@tonic-gate 1193*0Sstevel@tonic-gate=head1 HISTORY 1194*0Sstevel@tonic-gate 1195*0Sstevel@tonic-gateThis is a case of convergent evolution with Joshua Pritikin's Test 1196*0Sstevel@tonic-gatemodule. I was largely unaware of its existence when I'd first 1197*0Sstevel@tonic-gatewritten my own ok() routines. This module exists because I can't 1198*0Sstevel@tonic-gatefigure out how to easily wedge test names into Test's interface (along 1199*0Sstevel@tonic-gatewith a few other problems). 1200*0Sstevel@tonic-gate 1201*0Sstevel@tonic-gateThe goal here is to have a testing utility that's simple to learn, 1202*0Sstevel@tonic-gatequick to use and difficult to trip yourself up with while still 1203*0Sstevel@tonic-gateproviding more flexibility than the existing Test.pm. As such, the 1204*0Sstevel@tonic-gatenames of the most common routines are kept tiny, special cases and 1205*0Sstevel@tonic-gatemagic side-effects are kept to a minimum. WYSIWYG. 1206*0Sstevel@tonic-gate 1207*0Sstevel@tonic-gate 1208*0Sstevel@tonic-gate=head1 SEE ALSO 1209*0Sstevel@tonic-gate 1210*0Sstevel@tonic-gateL<Test::Simple> if all this confuses you and you just want to write 1211*0Sstevel@tonic-gatesome tests. You can upgrade to Test::More later (it's forward 1212*0Sstevel@tonic-gatecompatible). 1213*0Sstevel@tonic-gate 1214*0Sstevel@tonic-gateL<Test::Differences> for more ways to test complex data structures. 1215*0Sstevel@tonic-gateAnd it plays well with Test::More. 1216*0Sstevel@tonic-gate 1217*0Sstevel@tonic-gateL<Test> is the old testing module. Its main benefit is that it has 1218*0Sstevel@tonic-gatebeen distributed with Perl since 5.004_05. 1219*0Sstevel@tonic-gate 1220*0Sstevel@tonic-gateL<Test::Harness> for details on how your test results are interpreted 1221*0Sstevel@tonic-gateby Perl. 1222*0Sstevel@tonic-gate 1223*0Sstevel@tonic-gateL<Test::Unit> describes a very featureful unit testing interface. 1224*0Sstevel@tonic-gate 1225*0Sstevel@tonic-gateL<Test::Inline> shows the idea of embedded testing. 1226*0Sstevel@tonic-gate 1227*0Sstevel@tonic-gateL<SelfTest> is another approach to embedded testing. 1228*0Sstevel@tonic-gate 1229*0Sstevel@tonic-gate 1230*0Sstevel@tonic-gate=head1 AUTHORS 1231*0Sstevel@tonic-gate 1232*0Sstevel@tonic-gateMichael G Schwern E<lt>schwern@pobox.comE<gt> with much inspiration 1233*0Sstevel@tonic-gatefrom Joshua Pritikin's Test module and lots of help from Barrie 1234*0Sstevel@tonic-gateSlaymaker, Tony Bowden, chromatic and the perl-qa gang. 1235*0Sstevel@tonic-gate 1236*0Sstevel@tonic-gate 1237*0Sstevel@tonic-gate=head1 COPYRIGHT 1238*0Sstevel@tonic-gate 1239*0Sstevel@tonic-gateCopyright 2001 by Michael G Schwern E<lt>schwern@pobox.comE<gt>. 1240*0Sstevel@tonic-gate 1241*0Sstevel@tonic-gateThis program is free software; you can redistribute it and/or 1242*0Sstevel@tonic-gatemodify it under the same terms as Perl itself. 1243*0Sstevel@tonic-gate 1244*0Sstevel@tonic-gateSee F<http://www.perl.com/perl/misc/Artistic.html> 1245*0Sstevel@tonic-gate 1246*0Sstevel@tonic-gate=cut 1247*0Sstevel@tonic-gate 1248*0Sstevel@tonic-gate1; 1249