5

我正在练习使用 Module::Starter 制作一个新模块。我已经为一个包编写了一些测试用例,它们有时运行良好。

但是我注意到有两个问题:

  • 当测试用例失败时,我想在被测试的函数中放入一些打印语句。我跑了make test,它只告诉我我的测试用例失败了,它没有显示我的打印输出,尽管我真的很确定打印语句已经到达。

  • 假设我有三个测试用例来测试一个函数,我在函数内部放了一条打印语句,当测试用例运行时,它报告三个测试用例中只有一个运行了。如果我删除打印语句,所有三个测试用例都会运行。这是为什么?

这是我的代码:

# 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 ] } );
4

2 回答 2

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的文档,因为那里有很多有用的信息。

于 2012-08-23T21:10:43.207 回答
2

为了解决您的第二个问题,您需要小心地在测试脚本中写入标准输出。Test::More扫描标准输出,寻找像ok 5和一样的测试输出not ok 6 - disgronificator enabled。当您写入"lol"标准输出但不附加换行符时,测试模块将设置"lolok 9 - it works"并且不会将其识别为测试结果。(为了更有趣,print "not ";在所有测试之前放置语句)。

更好的做法就像 zostay 说的那样,写入标准错误,使用diag和提供的其他输出功能Test::More

于 2012-08-23T21:59:14.570 回答