如何调试Module :: Starter制作的模块?

时间:2012-08-23 20:58:18

标签: perl testing

我正在练习使用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 ] } );

2 个答案:

答案 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 5not ok 6 - disgronificator enabled等告密测试输出。当您将"lol"写入标准输出但不附加换行符时,测试模块将设置"lolok 9 - it works"并且不将其识别为测试结果。 (为了更有趣,在所有测试之前放置print "not ";语句。

更好的做法就像zostay所说,使用diagTest::More提供的其他输出函数来写入标准错误。