(1)はこちら、(2)はこちらから。
テスト関数の作り方
テストが大きくなってくると、複数のテスト間で共通して使えるテストの処理を1つの関数としてまとめたくなります。本節ではテスト関数の作成とそのテストの方法について解説します。
まずは、関数の中で通常と同じようにテスト関数を呼ぶようにしてみます。
この場合に問題となるのが、呼び出し元をテスト側に反映できないという点です。テストを実行して、失敗したときの出力を見てみます。(2)で失敗すると思われるテストは(1)(5行目)で失敗したことになっており、これではテスト結果がわかりにくいです。
この問題を解決するためには、is
やok
などのテスト関数の1つ上の呼び出し元が反映されるように伝える必要があります。Test::Builder
の場合は$Test::Builder::Level
というグローバル変数によって管理する必要がありましたが、Test2ではコンテキストと呼ばれるオブジェクトに隠蔽(いんぺい)されています。スコープの変更時にcontext
関数を呼び出すことでコンテキストを作り、抜けるときに作成したコンテキストのrelease
メソッドを呼び出します。こうすることで、テスト関数の呼び出し元を正しく反映できます。
テスト関数のテスト
テスト関数を書いたなら、その関数が正しいかどうかテストを書きたくなるはずです。Test2では、テストの結果をイベントと呼ばれる単位で取り出すことで、容易にテスト関数のテストができるようになっています。イベントはあるテストが成功したことや出力されたといった単位を表し、表4のようにいくつかの種類があります。
表4 イベントの種類
イベント名 | アクセサ | 説明 |
Ok | pass、effective_pass | okやis関数によるテストの結果が成功した場合はpassが1となり、todo関数によりテスト結果を無視する場合はeffective_passが1となる |
Diag | message | diag関数によってメッセージが出力された |
Note | message | note関数によってメッセージが出力された |
Skip | reason | skip関数によりテストがスキップされた |
Subtest | pass、effective_pass、subevents | subtest関数によりsubtest化されたテスト、subtest内で発行されたイベントはsubeventsに含まれる |
イベントの取り出し
イベントの取り出しには、intercept
関数を使います。コードブロック内で実行されたテストは実際には結果としては出力されず、イベントとして扱えます。取り出したイベントを比較して、テスト関数が正しく動いていることをテストできます。イベントの比較には、event
ビルダを使いチェックします。
次のコードでは、失敗するテストを例に、イベントを取り出して出力結果が意図したとおりかどうかをテストしています。
(1)では、イベントを取り出す対象となるテスト関数を呼び出しています。
(2)では、event
ビルダにより、Ok
イベントが発行されていてその結果が失敗していることをチェックしています。
(3)では、出力結果のテーブルを比較しています。message自体は文字列であるため、Test2::Util::Table
にあるテーブルを作るヘルパを利用しています。
なお、Test2::Tools::EventDumper
を使うことで、イベントからテストコードを生成できます。テストを書き始める際に使うと全体的なイベントの流れが理解しやすくなるでしょう。
テストモジュールの一例
ここでテストモジュールの一例として、筆者が開発したTest2::Tools::JSON
というモジュールを紹介します。このモジュールは、JSONの文字列をテスト内で比較できるようにしたもので、Test::Deep::JSON
をTest2用に書きなおしたものです。
使い方は、次のようにTest2::Tools::JSON
がエクスポートするjson
関数を使うことで、データ構造に含まれるJSONの文字列に対して比較を行えます。
上記のテスト中のJSONを{"a":2}
と書き換えて失敗させてみます。図2のように、出力結果をJSON向けにカスタマイズできるところがTest2の便利なところです。
まとめ
本稿では、新たなテスティングフレームワークであるTest2を使ったテストの方法について解説しました。Test2では、Test::Builder
の問題を解決し、Test2::V0
といった高機能なテストモジュールが使え、さらに従来のモジュールと比べるとテスト関数のテストが柔軟に行えます。
本稿で紹介したものは一部にすぎません。RSpecライクなテスト記法を提供するTest2::Workflow
や、prove
を置き換える形のテストランナーであるyath
など、Test2に関連する新たなツールが開発されています。みなさんも、これからテストを書く際はTest2を使ってみてください。
さて、次回の執筆者は小林謙太さんで、テーマは「Perlで堅牢な開発」です。お楽しみに。