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

理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

Test::Output

perl module

Perl というとテスト回りのモジュールが大変充実しておりまして,受験勉強の学生なんかメじゃないくらいに皆さんテストばっかしやっておられることでしょう.
ところでテスト対象となるのは基本的にはデータです.
データとはとかいうと何か深淵な議論になったり,哲学の分野に落ち込んだりしていろいろメンドいので,まぁこんな感じですね.

ok( pass(), "pass test" );
is( $got, $expected, "test name" );

関数/メソッドから返ってきたデータだったりを,予期している値と比べて,関数/メソッドやらが正しく実装されているかどうかを調べたりする.


ところで,もう一つのテストのパターンとして,標準出力に書き出した値が予期しているものと合っているのかどうかを調べるというものがある.
ぼくはこれまで,こういうテストは目視確認しかねーのかなーと思ってたんですけども,Mastering Perl を読んでたら,どうも Test::Output] とかあるみたいですね.

Mastering Perl

Mastering Perl

SYNOPSIS の一部を引用すると,以下のような感じで,標準出力(エラー出力も ok)に書き出した文字列が予期しているものかどうかをチェックできるようになって,これはなんかいいかんじだ.

    use Test::More tests => 4;
    use Test::Output;

    sub writer {
      print "Write out.\n";
      print STDERR "Error out.\n";
    }

    stdout_is(\&writer,"Write out.\n",'Test STDOUT');

内部構造

どうやってこれを実現してるのかなーとか思ってたんですけど,ソースを見ると内部で STDOUT を Test::Output::Tie に tie していたりします.これによって,標準出力に書き出されるはずの文字列は Test::Output::Tie に保持され,それを比較するという感じになります.なるほど,こうやって書けばすっきりするなー.

sub stdout_from (&) {
  my $test = shift;

  select( ( select(STDOUT), $| = 1 )[0] );
  my $out = tie *STDOUT, 'Test::Output::Tie';

  &$test;
  my $stdout = $out->read;

  undef $out;
  untie *STDOUT;

  return $stdout;
}