読者です 読者をやめる 読者になる 読者になる

Perl日記

PerlとかRubyとかPHPとかPythonとか

Testをはじめてみた4

モダンPerl入門」を読んで、Testに関して初めて分かったことメモ。
モダンPerl入門 (CodeZine BOOKS)
以下、だらだら箇条書き。

Test::More

  • use Test::More tests => 10; は、 use Test::More; plan(tests => 10); と同じ
    • むしろ環境でそのテストファイルを全部スキップなんかの場合には、plan()で指定すると綺麗。
    • plan(skip_all => $why) で全部スキップできるよ!
use Test::More;
eval { require MySpecial };
if ($@) {
  plan(skip_all => 'Not MySpecial');
}
else {
  plan(tests => 100);
}
  • TODOラベル内で、あとで作るはずの(ToDo)サブルーチンでdie()しちゃってテストが終わるのを避けたい。
    • todo_skip()を使いましょう。サブルーチンが完成したらtodo_skipを消しましょう。
      • [感想]大切なのはToDoであることを残しておくことってことか。
TODO : {
  todo_skip($why,      # 何故スキップ?
            $how_many, # 何個スキップ?
           );
  # Test Code From Here
  ok mysub(); # mysub()は実行されない
}

-テスト中にデバッグ文字列を表示したいんだけどSTDERRがTest::Moreにとられちゃってます>

    • diag()で出力してくれるよー。
my $ret = mysub(my $time = time);
if (!ok($ret)) { # ok()がokなら真, not okなら偽を返すのも初めて知った
  diag("mysub()で失敗。dbg => \$time:[$time], \$ret:[$ret]");
}
    • diag();diag();…と入れ込みまくってたらテストするたびにものすごい量が出力されて困ります。
      • note()を使うんだ。そうすれば prove -v されない限りそれは出ない。
      • ついでにバージョンなんかをnote()しておくと後々確認に便利。
note($debug_string);
note("CGI::VERSION:[$CGI::VERSION]");
    • だめです…。リファレンスを入れたらdiag()もnote()も「HASH(xxx)」みたいな風にしか出してくれません。
      • まだ諦めるな! Data::Dumper:Dumper()のようなexplain()を使え!
my $hash_ref = { key => 123 };
note("\$hashref is");
note(explain($hash_ref));
# 以下のように表示される。
# $hashref is
# {
#   'key' => 123
# }
  • use utf8してます。Wide charcter…がでてきてうんざりです…。
    • Test::Moreが使用するハンドルにutf8属性を指定するればよかろう。
my $builder = Test::More->builder;
binmode($builder->output,         ':utf8');
binmode($builder->failure_output, ':utf8');
binmode($builder->todo_output,    ':utf8');
    • もし毎回これをするのが面倒ならこれをクラスにしてくるんじゃえ。
package MyTestUTF8;
use Test::More;
BEGIN {
  my $builder = Test::More->builder;
  binmode($builder->output,         ':utf8');
  binmode($builder->failure_output, ':utf8');
  binmode($builder->todo_output,    ':utf8');
}
1;
__END__
use Test::More;
use MyTestUTF8;
      • ただしこれでencodeしているという意識を外してはならない。

いろいろなTestモジュール

  • Test::Exception
    • throws_ok()で例外を補足できる。
use Test::Exception;
sub mysub { die 'Please Argument!!!' unless @_ }
throws_ok { mysub() } qr/Please Argument!!!/, 'exist argument';

# throws_ok()のformat
#    throws_ok BLOCK REGEX, TEST_DESCRIPTION
#    throws_ok BLOCK CLASS, TEST_DESCRIPTION