我正在练习使用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;
}
这是测试用例:
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 ] } );
答案 0 :(得分:7)
您需要解决的测试存在一些问题以及您自己的问题。首先是你的问题:
如果要在测试中显示输出,则需要明确打印到标准错误。作为最佳做法,您还需要以#
开头的输出。 Test::More模块提供了可用于轻松完成此操作的工具。
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
如果您不想每次都打印该输出,但仅在请求详细日志记录时,您可以使用note
:
note("GOT $got");
当您使用prove -v
运行测试时,这非常有用:
prove -l -v t/test.t
还有一个explain
函数会转出复杂的输出以供查看:
diag explain $got;
# OR
note explain $got;
至于你的其他问题。通常最好使用is()
到ok()
:
is($got, 101); # gives slightly more readable output on error
此外,在测试复杂数据结构时,您需要使用is_deeply()
进行完整比较:
is_deeply($got, [1, 2, 3]);
你绝对应该看看Test::More的文档,因为那里有大量有用的信息。
答案 1 :(得分:2)
要解决第二个问题,您需要小心在测试脚本中写入标准输出。 Test::More
扫描标准输出,查找ok 5
和not ok 6 - disgronificator enabled
等告密测试输出。当您将"lol"
写入标准输出但不附加换行符时,测试模块将设置"lolok 9 - it works"
并且不将其识别为测试结果。 (为了更有趣,在所有测试之前放置print "not ";
语句。
更好的做法就像zostay所说,使用diag
和Test::More
提供的其他输出函数来写入标准错误。