Perl日記

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

Testをはじめてみた2

前回「Testをはじめてみた1 - Perl日記」の続き。
Test::More等について箇条書き。

  • オブジェクト指向のテスト
    • isa_ok() # 第一引数のobjが第二引数の所属クラスならok, 違うならnot ok
      • 継承もok
    • can_ok() # 第一引数のobjが第二引数のメソッドを呼び出せるならok, ダメならnot ok
#!/usr/bin/perl
# TestMore2.pl
use Test::More tests => 5;
use IO::File;
my $io = IO::File->new();
isa_ok($io, 'IO::File');
isa_ok($io, 'IO::Handle');
isa_ok($io, 'CGI');
can_ok($io, 'open');
can_ok($io, 'header');
% perl TestMore2.pl
1..5
ok 1 - The object isa IO::File
ok 2 - The object isa IO::Handle
not ok 3 - The object isa CGI
#   Failed test 'The object isa CGI'
#   at TestMore2.pl line 8.
#     The object isn't a 'CGI' it's a 'IO::File'
ok 4 - IO::File->can('open')
not ok 5 - IO::File->can('header')
#   Failed test 'IO::File->can('header')'
#   at TestMore2.pl line 10.
#     IO::File->can('header') failed
# Looks like you failed 2 tests of 5.
  • TODOラベル
    • 「失敗するのは分かっているのであとで対処する」という意味
    • $TODOに失敗理由を格納しておく
    • Test::MoreはTODOラベル内の失敗を失敗に数えない
      • 逆に成功してしまったら警告が出る
#!/usr/bin/perl
# TestMore3.pl
use Test::More tests => 1;
sub add10 {
  my $num = shift;
  # ★後で処理追加
  return $num;
}
TODO : {
  local $TODO = 'Not add Number to 10 yet'; # localにすること
  my $test_number = 90;
  cmp_ok(add10($test_number), '==', ($test_number + 10), 'add10() test');
}
% perl TestMore3.pl
1..1
not ok 1 - add10() test # TODO Not add Number to 10 yet
#   Failed (TODO) test 'add10() test'
#   at TestMore3.pl line 11.
#          got: 90
#     expected: 100
  • SKIPラベル
    • 「条件によってしなくてもいいテスト」
    • skip($reason, $how_maney)
      • Perlのバージョン
      • OS
      • オプションモジュールのインストール有無
#!/usr/bin/perl
# TestMore4.pl
use Test::More 'no_plan';
SKIP : {
  eval { require 'MyGreatestUtil' };
  if ($@) {
    skip('MyGreatestUtil is not available', 3);
  }
  ok(greate_1(), 'greate_1');
  ok(greate_2(), 'greate_2');
  ok(greate_3(), 'greate_3');
}
% perl TestMore4.pl 
ok 1 # skip MyGreatestUtil is not available
ok 2 # skip MyGreatestUtil is not available
ok 3 # skip MyGreatestUtil is not available
1..3

いろいろなTestモジュール

  • 長い文字列同士の比較
    • Test::LongString
      • is_string() # 第一引数と第二引数が異なっていたら、異なる箇所付近だけを結果表示
  • ファイル関連
    • Test::File
      • file_exists_ok() # 第一引数のファイルがあればok, なければnot ok
      • file_not_exists_ok() # file_exists_okの逆
      • file_not_empty_ok($file)
      • file_readable_ok($file)
      • file_min_size_ok($file, 500)
      • file_mode_is($file, 0775)
  • 出力関連
    • Test::Output
      • stdout_is($code_ref, $string) # 出力があるサブルーチンリファレンスと出力文字
      • stderr_like($code_ref, $regex) # 出力があるサブルーチンリファレンスと出力文字正規表現
#!/usr/bin/perl
# TestMore5.pl
use Test::More tests => 2;
use Test::Output;
sub stdout1 {
  print STDOUT 'Great!!!!';
}
sub stderr1 {
  print STDERR 'Too Bad....';
}
stdout_is(\&stdout1, 'Great!!!!');
stderr_like(\&stderr1, qr/Bad/);
% perl TestMore5.pl 
1..2
ok 1
ok 2