ソーシャルゲーム事業部のサーバサイドエンジニアの飛鷹です。
これはカヤックアドベントカレンダーの10日目の記事です。
今回は担当している案件でのTest2::V0を導入した話をします。
Test2導入経緯
担当している案件でperl 5.24からperl 5.26へのアップデート予定があり、バージョンを上げるのであればYAPC::Fukuokaで話のあったテスト結果がいい感じになると噂のTest2へと移行しようという試みでした。
Test2導入
Test2以前にもTest::SimpleやTest::Moreがあったように、Test2にも
Test2::Bundle::Extended | Old name for Test2::V0 |
Test2::Bundle::More | ALMOST a drop-in replacement for Test::More. |
Test2::Bundle::Simple | ALMOST a drop-in replacement for Test::Simple. |
Test2::V0 | 0Th edition of the Test2 recommended bundle. |
http://search.cpan.org/~exodist/Test2-Suite/
など色々種類があります。
それぞれのテストの環境にあったものを選択してもらうといいのですが、今回は0Th edition of the Test2 recommended bundle.
recommendと言われているTest2::V0
を使うことにしました。
テストをとりまく環境
Test::MoreでもTest2::V0でも大きく書き方の変更はありませんでした。
基本的には使うモジュールやテスト関数の変更のみで対応できました。
テストファイルの書き方
- テストファイルで
use t::Util;
している t/Util.pm
の中でTest2::V0の@EXPORT
をexportしたり、Test::mysqldを起動したり、Test::RedisServerを起動したりして、これさえuseしておけばDBでもKVSでも外部APIでも全てのテストができるようにしている- アプリケーションやマスタデータやデバッグ用のコードのテスト全てを含め、テストファイルは300程度、テストのステップ数は合計で3000程度
Test2への移行で変更したこと
Test::MoreからTest2::V0への移行で実際に使っていて置換したり実装の変更をしたものを一部紹介します。
この事例として紹介するものは私が担当した案件のもので、他の案件では使っているモジュールや書き方が異なると思うのでベストプラクティスとは限らないと思います。
use_okが使えない
Test::V0以外の他のTest::Suiteにもuseできるかのテスト関数がありませんでした。
use パッケージ名;
ができていればそもそもuse_okのはずなのでTest::V0導入でuse_okのテストを削除しました。
is_deeplyが使えない
正確にはTest2::Bundle::More
にはis_deeplyのテスト関数があるのですが実態はTest2::Tools::ClassicCompare
の中にあり、Test2::Tools::ClassicCompare - Classic (Test::More style) comparison tools.
との記載が。
せっかくTest2にしたから使わなくていいかという感じで、Test2::V0ではisやlikeで同様のことができるのでisとlikeに変更。
cmp_deeplyが使えない
Test2::Suiteにもないのでこちらもisとlikeに変更。
Test::Deep::Matcherが使えない
is_array_ref
, is_hash_ref
などTest::Deep::Matcher
のテスト関数をかなり多用していました。
Test2::V0にはそれらしきものがなくhash in hashなどを取り出してテストするように置き換えるのは工数的に厳しかったので、t::Util
に自前で正規表現を書きExportするようにしました。
Ref::Utilというのもあるようですが今後あまり増える予定もないので自前でやっています。
正規表現がかなり雑ですが、以前は時間でもis_string
を使ってテストしていましたが専用の正規表現をカジュアルに追加できるので結果としては良かったかなと思っています。
# t::Util sub is_array_ref { [] } sub is_datetime { qr/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$/ } sub is_hash_ref { +{} } sub is_http_url { qr/^http:\/\/.*$/ } sub is_https_url { qr/^https:\/\/.*$/ } sub is_integer { qr/^[0-9]+$/ } sub is_string { qr/^[a-zA-Z0-9]+$/ } sub is_text { qr/.*/ } # test my $result = get_response(); like $result, +{ player_id => is_integer, created_at => is_datetime, friend_ids => is_array_ref, };
Test::Mock::Guard call_countが使えない
テストに欠かせないTest::Mock::Guardですが、Test2ではメソッドをモックするものとしてTest2::Mock
があります。
しかしモックしたメソッドを何回呼ばれたかを知るcall_count
っぽい機能がない...
こちらもかなり使っていて自前で書き換えるのも辛かったのでモックはTest2::Mockへの移行は一旦留まりました。
See also
参考にさせていただきました。 ありがとうございます。
http://akiym.hateblo.jp/entry/2017/07/09/214116 http://kichijojipm.hatenablog.com/entry/2017/04/08/234936
まとめ
今回はTest2::Suiteの読み込みからはじまり、テストファイルが多いこともありやることは結構ありました。
途中Test2::Bundle::More
なら後方互換がかなりありそうなので、recommendを信じすぎてしまったか...と思いましたがなんとかTest2::V0
導入できました。
今回軽いノリで移行をスタートしてしまったので、雑になった部分もあって当たり前のことながら
- 使用しているテスト関数全ての洗い出し
- どのテスト関数がTest2::Suiteのモジュールに当てはまるのか
- どのテスト関数を移行するのかしないのか
- テスト関数が不足していた場合Test2::Suiteへ追加のPRを出せないか
をしっかり決めたうえで移行するとより綺麗で平和な開発ができるのかなと思いました。
明日11日目のカヤックアドベントカレンダーは、@handlenameさんです!
面白法人カヤックでは、空前絶後の超絶怒涛のPerl Monger、Perlを愛し、Perlに愛された男(女性でもPerlを愛していない方でも可)を募集しております!