5

I am practicing to make a new module using Module::Starter. I have written a few test cases for a package, and they run OK sometimes.

However I noticed there are two problems:

  • When the test cases fail, I want put some print statements in the function being tested. I ran make test and it only tells me that my test cases failed, it does not show my printed output, despite that I am really sure that the print statements are reached.

  • Say I have three test cases to test one function, I put a print statement inside the function, when the test cases run, it reports that only 1 out of the three test cases were run. If I remove the print statement, all three test cases will run. Why is that?

Here's my code:

# 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;
}

This is the test cases:

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

2 番目の質問に取り組むには、テスト スクリプトの標準出力への書き込みに注意する必要があります。やTest::Moreのような明確なテスト出力を探すために、標準出力をスキャンします。標準出力に書き込み、改行を追加しない場合、テスト モジュールはそれを設定し、テスト結果として認識しません。(さらに楽しむために、すべてのテストの前にステートメントを置きます)。ok 5not ok 6 - disgronificator enabled"lol""lolok 9 - it works"print "not ";

より良い方法は、zostay が言うように、提供diagされるその他の出力関数を使用して、標準エラーに書き込むことTest::Moreです。

于 2012-08-23T21:59:14.570 に答える