モダンPerlの世界へようこそ

第29回 Test::Base:データ本位のテストをするときは

この記事を読むのに必要な時間:およそ 4 分

テストは実行する前にも数えられるはず

前回前々回と見てきたように,Test Anything Protocolでは本来ひとつひとつのテストに連番が割り振られます。新しいテストを追加したければ,テストファイルの末尾に移動して,テスト番号をひとつずつ増やしながらテストを書き進め,終わったら先頭に戻って宣言部を更新する。先頭に戻るのが面倒であれば宣言部を末尾に移してもよいですが,いずれにしてもテストを追加し終わった時点でテストの件数はわかっているのですから,更新に困ることはないはずでした。

ところが,Perl 5の時代に入ってテスト用のモジュールが連番を振ってくれるようになった結果,テストの件数がわかりづらくなったため,no_planやdone_testingのように実際にテストを実行した回数をテストの総数とみなす手法が登場した――というのが前回の話でしたが,そういった妥協案は,Test Anything Protocolの大事なテストのひとつである「何らかの事情で抜け落ちてしまったテストがないか確認するテスト」を省略することで成り立っているもの。品質を維持するのが大変だからといってテストを削るようでは怠惰さが足りません。

今回はそのようなno_planやdone_testingの欠点をおぎなうために,テストを実行する前にテストの件数を調べる工夫をこらしたテストツールを紹介してみます。

ファイル探索型のテスト

テストの件数を自動的に検出するツールにも何通りかのパターンがありますが,おそらくもっともわかりやすいのはファイル探索型のテストでしょう。PODの書式に誤りがないかを確認するTest::Podや,公開されている関数,メソッドのドキュメントが不足していないかを確認するTest::Pod::Coverage特定の流儀にしたがった書き方をしているか確認するTest::Perl::Critic古いPerlをサポートしたいときに,古いバージョンのPerlでは動かない書き方をしていないか調べるTest::MinimumVersionコード内にハードタブが混じっていないかを確認するTest::NoTabsシステムにインストールされているスペルチェッカーを利用して英単語のスペルを確認するTest::Spellingモジュールやスクリプトが正しくロードできるか確認するTest::Compileなど,特定のディレクトリ配下にあるすべてのモジュールを対象とするタイプのテストモジュールは,いちいちテスト計画を宣言しなくても,テストモジュール側で見つけたファイルの数をテストの件数として宣言してくれるのが特徴です。

使い方はほとんど同じで,たいていの場合はモジュール本体と,必要であればTest::Moreを読み込んで,⁠all_..._ok()」のようなテストコマンドを実行するだけ。

use strict;
use Test::More;
use Test::Pod;

all_pod_files_ok();

なかにはあとで直すつもりで「FIXME」のような文字列を入れたまま放置しているモジュールがないか確認するTest::Fixmeのように「all_...ok()」以外のコマンドでテストを実行するものや,READMEやMANIFESTが存在しているか,use strictが使われているか,PODにエラーはないかといったディストリビューション全体の品質を確認するTest::Kwaliteeのようにロードしただけでテストを実行するものもありますが,これは例外的といってよいでしょう。

use strict;
use Test::Fixme;
run_tests;

モジュール作者専用のテスト

このようなファイル探索型のテストは,Test::Compileのように特定環境におけるモジュールの動作を確認するものもありますが,ほとんどの場合はどこで実行してもモジュールの動作には影響しない,全体的な品質を担保するものであると考えられます。

そのため,どこで実行しても同じなら,わざわざ多くのユーザにテストしてもらうまでもなく,作者だけが自分の環境で実行しておけば事足りるのではないか,という判断のもと,これらのテストは動作確認用のテストを入れておくt/ディレクトリではなく,作者テスト用のディレクトリとされているxt/ディレクトリに移したり,テストモジュールがインストールされていない場合やリリーステスト以外ではテストをスキップできるようにしたほうがよい,というのが最近のPerlテスト界の論調となっています※1)⁠

その際,昔は銘々が勝手にTEST_PODのような環境変数を設定していたものですが,このような変数が増えるとリリーステストのときに指定漏れが出やすくなりますし,自動テストもしづらくなるので,最近ではRELEASE_TESTINGやAUTOMATED_TESTINGといった環境変数に統一しようという話になっていることも頭の片隅に入れておいたほうがよいでしょう。

先ほどのテストであれば,たとえばこのように書き直せます。

use strict;
use Test::More;
eval "use Test::Pod 1.00";
plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
plan skip_all => "Author tests" unless $ENV{AUTOMATED_TESTING} or $ENV{RELEASE_TESTING};

all_pod_files_ok();

ただし,このようなリリーステストの扱いが定められたのは2008年4月にオスロで開催された品質保証チームのハッカソンでのことです。その成果はアダム・ケネディ氏の記事にまとまっていますが,これはあくまでも小さな分科会での合意にすぎないため,第26回で紹介したShipItをはじめとするリリースツール側の対応はまだ完全には終わっていません。テストをスキップさせるのに独自の環境変数を利用している方は上記の変数に移行したほうがよい,ということはいえますが,闇雲に上の書き方を真似してリリース時にテストを忘れるようでは本末転倒です。この種のテストはめったに更新する必要がない分,ほかのモジュールのテストやひな形からコピー&ペーストしたあとは環境変数の設定を忘れてしまいがちなので,環境変数によるスキップなどを有効にする場合は,お使いのリリースツールがその環境変数に対応しているかどうかを確認してからにすることをおすすめします。

※1

実際にはインストールされている関連モジュールのバージョンなどの影響で微妙に挙動が変わってしまうものもありますし,そもそもそのテスト自体がテストモジュールのテストになっているので,かならずしも作者の環境だけでテストすれば十分というものでもないのですが,ちょっとしたドキュメントのエラーでモジュールのインストールに失敗するのは不便だと考える人が多いのは仕方のないことですし,その結果force installやnotest installがはびこるくらいなら全体的な品質保証のテストは作者まかせにしたほうが無難というのも納得はできます。

著者プロフィール

石垣憲一(いしがきけんいち)

あるときは翻訳家。あるときはPerlプログラマ。先日『カクテルホントのうんちく話』(柴田書店)を上梓。最新刊は『ガリア戦記』(平凡社ライブラリー)。

URLhttp://d.hatena.ne.jp/charsbar/

コメント

コメントの記入