⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 more.pm

📁 SinFP是一种新的识别对方计算机操作系统类型的工具
💻 PM
📖 第 1 页 / 共 2 页
字号:
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.  Its 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);=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 to skip, $how_many tests there are,$why and under what $condition to skip them.  An example is theeasiest way to illustrate:    SKIP: {        skip "Pigs don't fly here", 2 unless Pigs->can('fly');        my $pig = Pigs->new;        $pig->takeoff;        ok( $pig->altitude > 0,         'Pig is airborne' );        ok( $pig->airspeed > 0,         '  and moving'    );    }If pigs cannot fly, the whole block of tests will be skippedcompletely.  Test::More will output special ok's which Test::Harnessinterprets as skipped tests.  Its important to include $how_many testsare in the block so the total number of tests comes out right (unlessyou're using C<no_plan>, in which case you can leave $how_many off ifyou like).Its perfectly safe to nest SKIP blocks.Tests are skipped when you B<never> expect them to B<ever> pass.  Likean optional module is not installed or the operating system doesn'thave some feature (like fork() or symlinks) or maybe you need anInternet connection and one isn't available.You don't skip tests which are failing because there's a bug in yourprogram.  For that you use TODO.  Read on.=for _FutureSee L</Why are skip and todo so weird?>=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;        URI::Geller->bend_spoon;        is( $spoon, 'bent',    "Spoon bending, that's original" );    }With a todo block, the tests inside are expected to fail.  Test::Morewill run the tests normally, but print out special flags indicatingthey are "todo".  Test::Harness will interpret failures as being ok.Should anything succeed, it will report it as an unexpected success.The nice part about todo tests, as opposed to simply commenting out ablock of tests, is it's like having a programmatic todo list.  You knowhow much work is left to be done, you're aware of what bugs there are,and you'll know immediately when they're fixed.Once a todo test starts succeeding, simply move it outside the block.When the block is empty, delete it.=item B<todo_skip>    TODO: {        todo_skip $why, $how_many if $condition;        ...normal testing code...    }With todo tests, its best to have the tests actually run.  That wayyou'll know when they start passing.  Sometimes this isn't possible.Often a failing test will cause the whole program to die or hang, eveninside an C<eval BLOCK> with and using C<alarm>.  In these extremecases you have no choice but to skip over the broken tests entirely.The syntax and behavior is similar to a C<SKIP: BLOCK> except thetests will be marked as failing but todo.  Test::Harness willinterpret them as passing.=cutsub todo_skip {    my($why, $how_many) = @_;    unless( defined $how_many ) {        # $how_many can only be avoided when no_plan is in use.        _carp "todo_skip() needs to know \$how_many tests are in the block"          unless $Test::Builder::No_Plan;        $how_many = 1;    }    for( 1..$how_many ) {        $Test->todo_skip($why);    }    local $^W = 0;    last TODO;}=back=head2 Comparison functionsNot everything is a simple eq check or regex.  There are times youneed to see if two arrays are equivalent, for instance.  For theseinstances, Test::More provides a handful of useful functions.B<NOTE> These are NOT well-tested on circular references.  Nor am Iquite sure what will happen with filehandles.=over 4=item B<is_deeply>  is_deeply( $this, $that, $test_name );Similar to is(), except that if $this and $that are hash or arrayreferences, it does a deep comparison walking each data structure tosee if they are equivalent.  If the two structures are different, itwill display the place where they start differing.Barrie Slaymaker's Test::Differences module provides more in-depthfunctionality along these lines, and it plays well with Test::More.B<NOTE> Display of scalar refs is not quite 100%=cutuse vars qw(@Data_Stack);my $DNE = bless [], 'Does::Not::Exist';sub is_deeply {    my($this, $that, $name) = @_;    my $ok;    if( !ref $this || !ref $that ) {        $ok = $Test->is_eq($this, $that, $name);    }    else {        local @Data_Stack = ();        if( _deep_check($this, $that) ) {            $ok = $Test->ok(1, $name);        }        else {            $ok = $Test->ok(0, $name);            $ok = $Test->diag(_format_stack(@Data_Stack));        }    }    return $ok;}sub _format_stack {    my(@Stack) = @_;    my $var = '$FOO';    my $did_arrow = 0;    foreach my $entry (@Stack) {        my $type = $entry->{type} || '';        my $idx  = $entry->{'idx'};        if( $type eq 'HASH' ) {            $var .= "->" unless $did_arrow++;            $var .= "{$idx}";        }        elsif( $type eq 'ARRAY' ) {            $var .= "->" unless $did_arrow++;            $var .= "[$idx]";        }        elsif( $type eq 'REF' ) {            $var = "\${$var}";        }    }    my @vals = @{$Stack[-1]{vals}}[0,1];    my @vars = ();    ($vars[0] = $var) =~ s/\$FOO/     \$got/;    ($vars[1] = $var) =~ s/\$FOO/\$expected/;    my $out = "Structures begin differing at:\n";    foreach my $idx (0..$#vals) {        my $val = $vals[$idx];        $vals[$idx] = !defined $val ? 'undef' :                       $val eq $DNE  ? "Does not exist"                                    : "'$val'";    }    $out .= "$vars[0] = $vals[0]\n";    $out .= "$vars[1] = $vals[1]\n";    $out =~ s/^/    /msg;    return $out;}=item B<eq_array>  eq_array(\@this, \@that);Checks if two arrays are equivalent.  This is a deep check, somulti-level structures are handled correctly.=cut#'#sub eq_array  {    my($a1, $a2) = @_;    return 1 if $a1 eq $a2;    my $ok = 1;    my $max = $#$a1 > $#$a2 ? $#$a1 : $#$a2;    for (0..$max) {        my $e1 = $_ > $#$a1 ? $DNE : $a1->[$_];        my $e2 = $_ > $#$a2 ? $DNE : $a2->[$_];        push @Data_Stack, { type => 'ARRAY', idx => $_, vals => [$e1, $e2] };        $ok = _deep_check($e1,$e2);        pop @Data_Stack if $ok;        last unless $ok;    }    return $ok;}sub _deep_check {    my($e1, $e2) = @_;    my $ok = 0;    my $eq;    {        # Quiet uninitialized value warnings when comparing undefs.        local $^W = 0;         if( $e1 eq $e2 ) {            $ok = 1;        }        else {            if( UNIVERSAL::isa($e1, 'ARRAY') and                UNIVERSAL::isa($e2, 'ARRAY') )            {                $ok = eq_array($e1, $e2);            }            elsif( UNIVERSAL::isa($e1, 'HASH') and                   UNIVERSAL::isa($e2, 'HASH') )            {                $ok = eq_hash($e1, $e2);            }            elsif( UNIVERSAL::isa($e1, 'REF') and                   UNIVERSAL::isa($e2, 'REF') )            {                push @Data_Stack, { type => 'REF', vals => [$e1, $e2] };                $ok = _deep_check($$e1, $$e2);                pop @Data_Stack if $ok;            }            elsif( UNIVERSAL::isa($e1, 'SCALAR') and                   UNIVERSAL::isa($e2, 'SCALAR') )            {                push @Data_Stack, { type => 'REF', vals => [$e1, $e2] };                $ok = _deep_check($$e1, $$e2);            }            else {                push @Data_Stack, { vals => [$e1, $e2] };                $ok = 0;            }        }    }    return $ok;}=item B<eq_hash>  eq_hash(\%this, \%that);Determines if the two hashes contain the same keys and values.  Thisis a deep check.=cutsub eq_hash {    my($a1, $a2) = @_;    return 1 if $a1 eq $a2;    my $ok = 1;    my $bigger = keys %$a1 > keys %$a2 ? $a1 : $a2;    foreach my $k (keys %$bigger) {        my $e1 = exists $a1->{$k} ? $a1->{$k} : $DNE;        my $e2 = exists $a2->{$k} ? $a2->{$k} : $DNE;        push @Data_Stack, { type => 'HASH', idx => $k, vals => [$e1, $e2] };        $ok = _deep_check($e1, $e2);        pop @Data_Stack if $ok;        last unless $ok;    }    return $ok;}=item B<eq_set>  eq_set(\@this, \@that);Similar to eq_array(), except the order of the elements is B<not>important.  This is a deep check, but the irrelevancy of order onlyapplies to the top level.=cut# We must make sure that references are treated neutrally.  It really# doesn't matter how we sort them, as long as both arrays are sorted# with the same algorithm.sub _bogus_sort { local $^W = 0;  ref $a ? 0 : $a cmp $b }sub eq_set  {    my($a1, $a2) = @_;    return 0 unless @$a1 == @$a2;    # There's faster ways to do this, but this is easiest.    return eq_array( [sort _bogus_sort @$a1], [sort _bogus_sort @$a2] );}=back=head2 Extending and Embedding Test::MoreSometimes the Test::More interface isn't quite enough.  Fortunately,Test::More is built on top of Test::Builder which provides a single,unified backend for any test library to use.  This means two testlibraries which both use Test::Builder B<can be used together in thesame program>.If you simply want to do a little tweaking of how the tests behave,you can access the underlying Test::Builder object like so:=over 4=item B<builder>    my $test_builder = Test::More->builder;Returns the Test::Builder object underlying Test::More for you to playwith.=cutsub builder {    return Test::Builder->new;}=back=head1 NOTESTest::More is B<explicitly> tested all the way back to perl 5.004.=head1 BUGS and CAVEATS=over 4=item Making your own ok()If you are trying to extend Test::More, don't.  Use Test::Builderinstead.=item The eq_* family has some caveats.=item Test::Harness upgradesno_plan and todo depend on new Test::Harness features and fixes.  Ifyou're going to distribute tests that use no_plan or todo yourend-users will have to upgrade Test::Harness to the latest one onCPAN.  If you avoid no_plan and TODO tests, the stock Test::Harnesswill work fine.If you simply depend on Test::More, it's own dependencies will cause aTest::Harness upgrade.=back=head1 HISTORYThis is a case of convergent evolution with Joshua Pritikin's Testmodule.  I was largely unaware of its existence when I'd firstwritten my own ok() routines.  This module exists because I can'tfigure out how to easily wedge test names into Test's interface (alongwith a few other problems).The goal here is to have a testing utility that's simple to learn,quick to use and difficult to trip yourself up with while stillproviding more flexibility than the existing Test.pm.  As such, thenames of the most common routines are kept tiny, special cases andmagic side-effects are kept to a minimum.  WYSIWYG.=head1 SEE ALSOL<Test::Simple> if all this confuses you and you just want to writesome tests.  You can upgrade to Test::More later (its forwardcompatible).L<Test::Differences> for more ways to test complex data structures.And it plays well with Test::More.L<Test> is the old testing module.  Its main benefit is that it hasbeen distributed with Perl since 5.004_05.L<Test::Harness> for details on how your test results are interpretedby Perl.L<Test::Unit> describes a very featureful unit testing interface.L<Test::Inline> shows the idea of embedded testing.L<SelfTest> is another approach to embedded testing.=head1 AUTHORSMichael G Schwern E<lt>schwern@pobox.comE<gt> with much inspirationfrom Joshua Pritikin's Test module and lots of help from BarrieSlaymaker, Tony Bowden, chromatic and the perl-qa gang.=head1 COPYRIGHTCopyright 2001 by Michael G Schwern E<lt>schwern@pobox.comE<gt>.This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.See F<http://www.perl.com/perl/misc/Artistic.html>=cut1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -