テスト・スイートとは、POPFile のコードすべての行のテストを可能にするスクリプトとファイルの集まりのことです。プログラマはみんな知っているように、プログラムに機能を追加したり、バグを修正したときでさえ、無関係に見えるコードが動かなくなってしまう場合があります。テスト・スイートは、POPFile が予定どおりに動くことを確認することで、バグを防ぐ助けとなります。
テスト・スイートを構成するファイルが必要です。これは、CVS で入手します。 これらのファイルは普通に POPFile をダウンロードしても入っていません。
POPFile engine について、チェックアウトあるいはアップデートします:
cvs -d:pserver:[email protected]:/cvsroot/popfile login cvs -z3 -d:pserver:[email protected]:/cvsroot/popfile co engine
(もしエラーが起こったときは、何度か試してみてください。sourceforge への匿名での CVS へのアクセスは、よく混んでいます)
テスト・スイートを実行したり、あなたが作ったパッチについてのテストを作成したりするためには、いくつかのツールが必要です。特に、以下のプログラムが必要です:
Perl はすでにインストールしてあると思いますが、他のツールが必要ならば、 ツールのページ を参照してください。これらすべてのプログラムが、パスの通った場所にインストールされていることを確認してください。
コマンドライン / コンソールウィンドウを開いて、POPFile とテスト・スイートがインストールされたディレクトリに移動して、以下のように入力します:
make test
これによって、すべてのテストが実行されます。テストにはしばらく時間がかかります。
特定のテスト(例えば、特定のモジュールについてのテスト)を実行したい場合は、以下のようにします:
make test TESTARGS=モジュール名
これによって、ひとつのモジュールについてのテストが実行されます(テストが存在する場合だけ)。モジュール名は大文字小文字を区別することに注意してください。
Windows で、cygwin パッケージを使用していない場合は、make を実行する前に以下のコマンドを実行してください:
attrib -r -h -s *.* /s /d
Windows の rm は、(unix のものとは) 違い、テスト・スイートがエラーなく通過するために削除しなければいけないディレクトリを削除しないのです。
上記のコマンドのどれかを実行したとき、make は POPFile ディレクトリにある “tests.pl” スクリプトを実行します。これは短い Perl のスクリプトで、テストを実行し結果をレポートします。また、スクリプトには、いくつかのテスト用の関数(下記を参照)が含まれています。テスト自体は tests/Test*.tst であらわすことができるファイルに入っています。すなわち、これらのファイルは “tests” サブディレクトリの中にあって、ファイル名が “Test” で始まり、“.tst” という拡張子がついています。
この .tst ファイルは、実際には Perl のスクリプトです。これらのスクリプトは POPFile と必要なモジュールを起動させ、テスト作業を行い、POPFile を終了させます。
この “テスト作業” は本当に簡単なものです。POPFile にあるデータを与えて、その結果が正しいかどうかを確認するのです。これにはいくつかの方法があります。以下は、いくつかの例です:
最初の 2 つは “TestMailParse.tst” で見つけられるでしょう:
test_assert( $b->start() );
test_assert は 上に書いた tests.pl のテスト関数のひとつです。これは Bayes.pm の start() 関数の返り値が真 (true) かどうかをチェックするために使用されます。何かが真 (true) あるいは null でないことを確かめたいときに test_assert() を使用します。他のテスト関数と同じように、(値が真であるというような) アサーション(成立すべき条件)が満たされない場合に test.pl にエラーメッセージを発生させます。
test_assert_equal( $cl->map_color( 'red' ), 'ff0000' );
test_assert_equal() は 2 つの値が等しいことを確かめたいときに使用します。この (例の) 場合、MailParse.pm の関数 map_color() の返り値が望んだ値と比較されます。言い換えれば、上記のコードは MailParse:map_color() が “red” (赤) という色の定義を 16 進数の値 “ff0000” に対応づけられることを確かめるものです。
test_assert_regexp( $temp, 'before' );
この例は TestBayes.tst で使用されているものです。これは、ある正規表現がある文字列にマッチすることを主張しています。ここでは、$temp に含まれる文字列が 'before' という正規表現にマッチしなければなりません。
test_assert_regexp() と対になるものとして test_assert_not_regexp() があります。これは文字列が正規表現にマッチしないことを主張しています。
engine ディレクトリには Makefile があります。これはいろいろなことができますが、その中に、test と coverage という 2 つのターゲットがあります。これらはいずれも tests/ ディレクトリの Makefile に渡されます。このファイルが、これらのターゲットに対してなにをすればよいのかを知っているのです。
ですから、engine ディレクトリで make test と入力した場合、tests/ ディレクトリで make test が実行され、engine ディレクトリにある Perl スクリプト、tests.pl が実行されるでしょう。tests.pl は実行されるテストを管理します。
tests.pl は tests/ ディレクトリの中でファイル名が .tst で終わるファイルを探します。これらのファイルは POPFile のモジュールに関連づけられています(例えば、TestWordMangle.tst というテストは、WordMangle.pm というモジュールに関連づけられています)。tst ファイル(通常は Perl スクリプトそのものです)の中には、test_assert や test_assert_equal といったアサーション(成立すべき条件)が含まれていて、それらは何かが真でなければならないということを調べるために使用されます。
例えば、TestWordMangle.tst には、以下のようなアサーションがあります:
test_assert_equal( $w->mangle( 'BIGWORD' ), 'bigword' ); test_assert_equal( $w->mangle( 'BIG+/?*|()[]{}^$.WORD' ), 'big..............word'); test_assert_equal( $w->mangle('awordthatisfartolongtobeacceptableforuseinclassification' ), // ); test_assert_equal( $w->mangle( 'A1234BEF66' ), // ); test_assert_equal( $w->mangle( 'BIG:WORD' ), 'bigword' ); test_assert_equal( $w->mangle( 'BIG:WORD', 1 ), 'big:word' );
それぞれの行は、mangle() API を調べて、正しい結果が出力されるかどうかを確認しています。もし正しい結果が出力されなければ、tests.pl はそれをメモしておいて、最後に詳しいエラーメッセージを表示します。もし問題がなければ、tests.pl は単に数を覚えておきます。
最後に、tests.pl は実行結果を要約したものを出力します。
できるすべてのテストを行ったことを示すために、補償範囲のオプションがあります。 これは、POPFile のソースファイルで、テスト・スイートによって実際に実行された 行数の割合を数えます。実行するにはgmake coverage を行うと、テスト・スイートが実施され、どの行が実行されたかを記録します。 最後に、実行された行数に関するサマリーが出力されます。 目標は、POPFile のソースの100%がテストされることです ( とても大変な目標です )。 最後に、テストされたファイル毎に HTML ファイルを書き出し、 実行された行数とそうでない行数を知ることができます。ここに MailParse.pm の例があります: http://popfile.sourceforge.net/MailParse.html 緑の行はテストされたもので、赤い行はテストされていません。
Should you find anything in the documentation that is incomplete, unclear, outdated or just plain wrong, please let us know and leave a note in the Documentation Forum.