Perl Hackers Hub

第51回 Test2で変わるモダンなテスト―拡張性を持ったテスティングフレームワークとTest2::V0の使い方(1)

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

本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーはakiymこと秋山卓巳さんで,テーマは「Test2で変わるモダンなテスト」です。新たなテスティングフレームワークであるTest2を使ったテストの書き方や活用方法について紹介します。

本稿のサンプルコードは,本誌「WEB+DB PRESS Vol.106」サポートサイトから入手できます。

Perlでのテスト

Perlではテストを書く際に,Test::Moreというモジュールが広く使われています。これは,プログラムの実行結果が期待しているものと一致しているかをチェックするためのシンプルなモジュールで,テスト結果をTAPTest Anything Protocol形式で出力します注1)⁠

本稿のテーマであるTest2は,Test::Moreなどのバックエンドとして使われているTest::Builderを置き換えるべく開発されているテスティングフレームワークです。2015年ごろよりChad Granum氏によって作られています。

注1)
Perlでの基本的なテストの方法に関しては,本連載第36回Perlのテストモジュールの使い方・作り方―Test::More,Test::Builder,Test::Stream,そしてPerl 6を参照してください。

Test::Builderの問題点

Test::Builderは,Perlにおけるテストモジュールが行う基本的な動作を扱い,それをTAP形式で出力するモジュールです。

Test::Builderの問題として,2001年ごろに作られたコードがメンテナンスされ使われ続けているため,拡張して使うのが難しいことがあります。テスト結果はTAP形式で出力されるため,1つのテストの結果が行単位で表され構造化されていないことから,テストモジュールのテストが困難になります。また,テスト出力のカスタマイズは,Test::Builderの関数を直接上書きするモンキーパッチによる対応でしか行えない状況でした。

この問題を解決するため,拡張性に重点を置いた新たなテスティングフレームワークとしてTest2が開発されました。

ちなみに,Test::Builderは今後どうなるのでしょうか。メンテナンスされないまま,古いコードが残っていくのでしょうか。実は,Test::Builderの内部ではTest2のAPIを呼び出すように書きなおされており,すでに全面的な新規コードでの置き換えがされています。そのため,古いインタフェースを使っている既存のテストモジュールはそのままで,新たに書き始めるテストモジュールは柔軟なインタフェースを持つTest2を使えます。

Test2にすると変わること

Test2は,Test::BuilderTest::Moreが含まれるTest-Simpleディストリビューションのバージョン1.3以降から使われるようになっています。また,Perl 5.26.0から標準モジュールとして同梱されるようになりました。

気になるのは,今動いている既存のテストをTest2にしたときにどうなるかでしょう。基本的には,Test::MoreをはじめとするTest::Builderを使った既存のテストモジュールが壊れることがないように,後方互換性を維持しつつ開発されています。ただし例外として,Test::Builderをモンキーパッチによって拡張していた場合には正しく動作しないことがあります。また,いくつかのテストモジュールは,バージョンアップが必要になったり使えなくなったりします。詳しくは,Test2::Transionを参照してください。

Test2::V0を使ったテスト

ここからは,Test2の拡張性をもとにして作られたテストモジュールTest2::V0を使ったテストを紹介します。Test2::V0はTest2の作者によって作られた,Test2-Suiteディストリビューションに含まれるモジュールです。Test2はフレームワークであるため基本的な機能しか提供されていませんが,Test2::V0では一歩踏み込んだ機能が実装されています。Test::Moreで提供されるテスト関数が使えるのはもちろんのこと,複雑なデータ構造の比較やオブジェクトのモックといったテストにおけるさまざまな操作を行えます。

まずはcpanmコマンドにより必要なモジュールをインストールします。Test2::V0をインストールすると,Test-SimpleTest2-Suiteディストリビューションに含まれるモジュールも一緒にインストールされます。

$ cpanm Test2::V0

なお,本稿ではPerl 5.26.2,Test-Simple 1.302136,Test2-Suite 0.000114を前提として説明します。

use Test2::V0と書くことで,テストを行うための関数のエクスポートや,テストでの共通した処理の実行などをしてくれます。これはいわゆるボイラープレート(お決まりのテンプレート)の役割を果たします。

実際にビルトイン関数の動作を確かめる単純なテストを書いてみます。ここでは,Test2::V0ok関数を使って,あるコードによる動作が正しい条件かどうかをテストします。

ucfirst.t

use Test2::V0;
ok ucfirst('foo') eq 'Foo',
  '先頭の文字がuppercaseになっている';
ok uc('foo') ne 'foo', 'fooとは一致しない';
done_testing;

これ以降に登場するコードでは,先頭のuse Test2::V0;は省略します

テストを実行すると次の結果が出力され,2つのテストが成功し,コードが意図したとおりに動作していることがわかります。

ucfirst.tの実行結果

$ perl ucfirst.t
# Seeded srand with seed '20180625' from local date.
ok 1 - 先頭の文字がuppercaseになっている
ok 2 - fooとは一致しない
1..2

著者プロフィール

秋山卓巳(あきやまたくみ)

1995年北海道生まれ。YAPC::Asia 2011にて当時高校生としてYAPCスピーカーデビュー。2017年より株式会社はてなに入社後,マンガサービスに携わる。

Twitter:@akiym
URL:https://akiym.com/