📄 more.pm
字号:
is()'s use of C<eq> will interfere: cmp_ok( $big_hairy_number, '==', $another_big_hairy_number );=cutsub cmp_ok($$$;$) { $Test->cmp_ok(@_);}=item B<can_ok> can_ok($module, @methods); can_ok($object, @methods);Checks to make sure the $module or $object can do these @methods(works with functions, too). can_ok('Foo', qw(this that whatever));is almost exactly like saying: ok( Foo->can('this') && Foo->can('that') && Foo->can('whatever') );only without all the typing and with a better interface. Handy forquickly testing an interface.No matter how many @methods you check, a single can_ok() call countsas one test. If you desire otherwise, use: foreach my $meth (@methods) { can_ok('Foo', $meth); }=cutsub can_ok ($@) { my($proto, @methods) = @_; my $class = ref $proto || $proto; unless( @methods ) { my $ok = $Test->ok( 0, "$class->can(...)" ); $Test->diag(' can_ok() called with no methods'); return $ok; } my @nok = (); foreach my $method (@methods) { local($!, $@); # don't interfere with caller's $@ # eval sometimes resets $! eval { $proto->can($method) } || push @nok, $method; } my $name; $name = @methods == 1 ? "$class->can('$methods[0]')" : "$class->can(...)"; my $ok = $Test->ok( !@nok, $name ); $Test->diag(map " $class->can('$_') failed\n", @nok); return $ok;}=item B<isa_ok> isa_ok($object, $class, $object_name); isa_ok($ref, $type, $ref_name);Checks to see if the given $object->isa($class). Also checks to makesure the object was defined in the first place. Handy for this sortof thing: my $obj = Some::Module->new; isa_ok( $obj, 'Some::Module' );where you'd otherwise have to write my $obj = Some::Module->new; ok( defined $obj && $obj->isa('Some::Module') );to safeguard against your test script blowing up.It works on references, too: isa_ok( $array_ref, 'ARRAY' );The diagnostics of this test normally just refer to 'the object'. Ifyou'd like them to be more specific, you can supply an $object_name(for example 'Test customer').=cutsub isa_ok ($$;$) { my($object, $class, $obj_name) = @_; my $diag; $obj_name = 'The object' unless defined $obj_name; my $name = "$obj_name isa $class"; if( !defined $object ) { $diag = "$obj_name isn't defined"; } elsif( !ref $object ) { $diag = "$obj_name isn't a reference"; } else { # We can't use UNIVERSAL::isa because we want to honor isa() overrides local($@, $!); # eval sometimes resets $! my $rslt = eval { $object->isa($class) }; if( $@ ) { if( $@ =~ /^Can't call method "isa" on unblessed reference/ ) { if( !UNIVERSAL::isa($object, $class) ) { my $ref = ref $object; $diag = "$obj_name isn't a '$class' it's a '$ref'"; } } else { die <<WHOA;WHOA! I tried to call ->isa on your object and got some weird error.This should never happen. Please contact the author immediately.Here's the error.$@WHOA } } elsif( !$rslt ) { my $ref = ref $object; $diag = "$obj_name isn't a '$class' it's a '$ref'"; } } my $ok; if( $diag ) { $ok = $Test->ok( 0, $name ); $Test->diag(" $diag\n"); } else { $ok = $Test->ok( 1, $name ); } return $ok;}=item B<pass>=item B<fail> pass($test_name); fail($test_name);Sometimes you just want to say that the tests have passed. Usuallythe case is you've got some complicated condition that is difficult towedge into an ok(). In this case, you can simply use pass() (todeclare the test ok) or fail (for not ok). They are synonyms forok(1) and ok(0).Use these very, very, very sparingly.=cutsub pass (;$) { $Test->ok(1, @_);}sub fail (;$) { $Test->ok(0, @_);}=back=head2 DiagnosticsIf you pick the right test function, you'll usually get a good idea ofwhat went wrong when it failed. But sometimes it doesn't work outthat way. So here we have ways for you to write your own diagnosticmessages which are safer than just C<print STDERR>.=over 4=item B<diag> diag(@diagnostic_message);Prints a diagnostic message which is guaranteed not to interfere withtest output. Handy for this sort of thing: ok( grep(/foo/, @users), "There's a foo user" ) or diag("Since there's no foo, check that /etc/bar is set up right");which would produce: not ok 42 - There's a foo user # Failed test (foo.t at line 52) # Since there's no foo, check that /etc/bar is set up right.You might remember C<ok() or diag()> with the mnemonic C<open() ordie()>.B<NOTE> The exact formatting of the diagnostic output is stillchanging, but it is guaranteed that whatever you throw at it it won'tinterfere with the test.=cutsub diag { $Test->diag(@_);}=back=head2 Module testsYou usually want to test if the module you're testing loads ok, ratherthan just vomiting if its load fails. For such purposes we haveC<use_ok> and C<require_ok>.=over 4=item B<use_ok> BEGIN { use_ok($module); } BEGIN { use_ok($module, @imports); }These simply use the given $module and test to make sure the loadhappened ok. It's recommended that you run use_ok() inside a BEGINblock so its functions are exported at compile-time and prototypes areproperly honored.If @imports are given, they are passed through to the use. So this: BEGIN { use_ok('Some::Module', qw(foo bar)) }is like doing this: use Some::Module qw(foo bar);don't try to do this: BEGIN { use_ok('Some::Module'); ...some code that depends on the use... ...happening at compile time... }instead, you want: BEGIN { use_ok('Some::Module') } BEGIN { ...some code that depends on the use... }=cutsub use_ok ($;@) { my($module, @imports) = @_; @imports = () unless @imports; my $pack = caller; local($@,$!); # eval sometimes interferes with $! eval <<USE;package $pack;require $module;'$module'->import(\@imports);USE my $ok = $Test->ok( !$@, "use $module;" ); unless( $ok ) { chomp $@; $Test->diag(<<DIAGNOSTIC); Tried to use '$module'. Error: $@DIAGNOSTIC } return $ok;}=item B<require_ok> require_ok($module);Like use_ok(), except it requires the $module.=cutsub require_ok ($) { my($module) = shift; my $pack = caller; local($!, $@); # eval sometimes interferes with $! eval <<REQUIRE;package $pack;require $module;REQUIRE my $ok = $Test->ok( !$@, "require $module;" ); unless( $ok ) { chomp $@; $Test->diag(<<DIAGNOSTIC); Tried to require '$module'. Error: $@DIAGNOSTIC } return $ok;}=back=head2 Conditional testsSometimes running a test under certain conditions will cause thetest script to die. A certain function or method isn't implemented(such as fork() on MacOS), some resource isn't available (like a net connection) or a module isn't available. In these cases it'snecessary to skip tests, or declare that they are supposed to failbut will work in the future (a todo test).For more details on the mechanics of skip and todo tests seeL<Test::Harness>.The way Test::More handles this is with a named block. Basically, ablock of tests which can be skipped over or made todo. It's best if Ijust show you...=over 4=item B<SKIP: BLOCK> SKIP: { skip $why, $how_many if $condition; ...normal testing code goes here... }This declares a block of tests that might be skipped, $how_many teststhere are, $why and under what $condition to skip them. An example isthe easiest way to illustrate: SKIP: { eval { require HTML::Lint }; skip "HTML::Lint not installed", 2 if $@; my $lint = new HTML::Lint; isa_ok( $lint, "HTML::Lint" ); $lint->parse( $html ); is( $lint->errors, 0, "No errors found in HTML" ); }If the user does not have HTML::Lint installed, the whole block ofcode I<won't be run at all>. Test::More will output special ok'swhich Test::Harness interprets as skipped, but passing, tests.It's important that $how_many accurately reflects the number of testsin the SKIP block so the # of tests run will match up with your plan.It's perfectly safe to nest SKIP blocks. Each SKIP block must havethe label C<SKIP>, or Test::More can't work its magic.You don't skip tests which are failing because there's a bug in yourprogram, or for which you don't yet have code written. For that youuse TODO. Read on.=cut#'#sub skip { my($why, $how_many) = @_; unless( defined $how_many ) { # $how_many can only be avoided when no_plan is in use. _carp "skip() needs to know \$how_many tests are in the block" unless $Test::Builder::No_Plan; $how_many = 1; } for( 1..$how_many ) { $Test->skip($why); } local $^W = 0; last SKIP;}=item B<TODO: BLOCK> TODO: { local $TODO = $why if $condition; ...normal testing code goes here... }Declares a block of tests you expect to fail and $why. Perhaps it'sbecause you haven't fixed a bug or haven't finished a new feature: TODO: { local $TODO = "URI::Geller not finished"; my $card = "Eight of clubs"; is( URI::Geller->your_card, $card, 'Is THIS your card?' ); my $spoon;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -