我正在练习使用Module :: Starter创建一个新模块.我为包编写了一些测试用例,有时它们运行正常.
但是我注意到有两个问题:
当测试用例失败时,我想在正在测试的函数中放入一些print语句.我跑了make test,它只告诉我我的测试用例失败了,它没有显示我的打印输出,尽管我确实已经达到了打印语句.
假设我有三个测试用例来测试一个函数,我在函数内部放了一个print语句,当测试用例运行时,它会报告三个测试用例中只有一个被运行.如果我删除print语句,则将运行所有三个测试用例.这是为什么?
这是我的代码:
# package declaration and stuff...
sub get_in {
my ( $hash, @path ) = @_;
my $ref = $hash;
print 'lol'; # This is the troublesome print statement. Remove this statement and all three test cases will run and pass
foreach (@path) {
if ( ref($ref) eq 'HASH' && exists $ref->{$_} ) {
$ref = $ref->{$_};
} else {
return undef;
}
}
return $ref;
}
Run Code Online (Sandbox Code Playgroud)
这是测试用例:
use Test::More tests => 3;
use strict;
use warnings;
use diagnostics;
require_ok('Foo::Doc');
ok( Foo::Doc::get_in( { 'a' => { 'b' => { 'c' => 101 } } }, 'a', 'b', 'c' ) == 101 );
ok( @{ Foo::Doc::get_in( { 'a' => { 'b' => { 'c' => [ 1, 2, 3 ] } } }, 'a', 'b', 'c' ) } == @{ [ 1, 2, 3 ] } );
Run Code Online (Sandbox Code Playgroud)
您需要解决的测试以及您自己的问题本身存在一些问题.首先你的问题:
如果要在测试中显示输出,则需要显式打印到标准错误.作为最佳实践,您还需要输出前缀#.该测试::更多模块,提供了可用于轻松地做到这一点的工具.
my $got = Foo::Doc::get_in( { 'a' => { 'b' => { 'c' => 101 } } }, 'a', 'b', 'c' );
ok($got == 101); # you probably want is() instead, see below
diag("GOT $got"); # outputs "# GOT 101" or whatever to STDERR
Run Code Online (Sandbox Code Playgroud)
如果您不想每次都打印该输出,但仅在请求详细日志记录时,您可以使用note:
note("GOT $got");
Run Code Online (Sandbox Code Playgroud)
当您用于prove -v运行测试时,这非常有用:
prove -l -v t/test.t
Run Code Online (Sandbox Code Playgroud)
还有一个explain函数可以转储复杂的输出以供查看:
diag explain $got;
# OR
note explain $got;
Run Code Online (Sandbox Code Playgroud)
至于你的其他问题.通常最好is()用于ok():
is($got, 101); # gives slightly more readable output on error
Run Code Online (Sandbox Code Playgroud)
此外,在测试复杂的数据结构时,您需要使用它is_deeply()来进行完整的比较:
is_deeply($got, [1, 2, 3]);
Run Code Online (Sandbox Code Playgroud)
你一定要看一下Test :: More的文档,因为那里有很多有用的信息.