マナリンクではかれこれ2年くらいPHPUnitでテストコードを書いていますが、恥ずかしながらこれまでカバレッジを取得したことがなかったので、方法を調べて簡単にまとめてみました。
※ざっと3時間くらい調べたり試した内容を記載しているため、今後修正したり、運用を改善する可能性があります。
テストカバレッジとは
テストコードがソースコード(プロダクトコード)のうちどれくらいの割合を実行しているかを示す指標のことです。
せっかくテストコードを書いていても、プロダクトコードのうちほんの一部しか実行していなければ、漏れが多いと言えます。テストカバレッジを計測することで、どの程度テストコードが網羅できているかの一つの指標になります。
補足:テストカバレッジがあまりに低いコードはテストが足りていないといえますが、一方で、テストカバレッジが100%に近いからといって完璧にテストできていると言えるわけではありません。あくまでテストカバレッジは実行されたかを取得するのであって、どのようなデータに対してどのような手順でテストしたか、それによってどんなユースケースをカバーしているのかといった点は人間が判断する必要があります。そのため、テストカバレッジを上げるのは大事ですが、ある程度以上に上げるために努力するのであれば、各テストケースが論理的に意味のあるものなのかをレビューするほうが重要と言えます。
以下記事によると、いったんは85%程度を指標にするのがよさそうです。それ以下なら改善が必要で、それ以上なら論理的に意味のあるテストケースかレビューすることに軸足を置く感じでしょうか。
https://qiita.com/bremen/items/d02eb38e790b93f44728
xdebugでテストカバレッジを取得してみる
xdebugとは
xdebugとはPHPの拡張機能の一つで、開発者体験の向上のためのいくつかの機能を備えています。
今回はxdebugの中のテストカバレッジ取得機能を使ってみます。
補足:xdebug以外にも、phpdbgやPCOVといったカバレッジ測定ツールがあるようですが、こちらの比較はまだしていません。PHPUnit公式ドキュメントにxdebugの紹介が書いてあったこと、また、xdebug3へのメジャーアップデートにて速度の改善が行われたという情報もあり、ベターな選択肢ではあると思います。
環境構築
環境構築は概ね以下の手順で実行します。Dockerベースで構築する場合は、最初にDockerfileを書けば、以後は各開発者がどうこうすることはありません。
- Dockerfileにてxdebugのインストールコマンドを追記する
- php.iniにxdebugの設定を書く
- Dockerfileでコンテナをビルド
- composer.jsonにscriptを書く(一例)
Dockerfile
マナリンクではalpine linuxベースのDockerfileを使っています。
追加で必要なコマンドは以下のとおりです。
apk add gcc g++ make autoconf
pecl install xdebug
docker-php-ext-enable xdebug
php.ini
一例ですが以下のような設定を書きます。細かいですがxdebug.modeにはカンマ区切りで複数指定できます。
[xdebug]
xdebug.mode=debug,coverage
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.log=/tmp/xdebug.log
xdebug.client_port=9200
https://polidog.jp/2021/09/16/php-xdebug/
https://qiita.com/ucan-lab/items/fbf021bf69896538e515
composer.jsonのスクリプトを追加
"test": "vendor/bin/phpunit --coverage-html coverage-result"
実行結果
ここまで終わった状態で以下コマンドを実行することで、テストコードを実行しつつ最後にカバレッジレポートを吐き出します。
docker-compose exec {PHPコンテナ名} composer test
指定したディレクトリにHTMLを吐き出すので、index.htmlを開くと以下のようにカラフルなレポートを見ることが出来ます。
サービスのコアロジックを記載しているDomainディレクトリで、しっかり85%を出せていることがわかりました。細かく内容を見ると、ファイルごとに分岐でどこを通っていないかなども書いてあるため改善に役立てられそうです。
たとえば以下のように、NULLを返すパターンについてチェックできていないパターンがわかります。
今後の運用案
codecov
CodecovというサービスをよくOSSのリポジトリで見ます。これをXdebugとCI上で連携することができるようです。
ただ、プライベートリポジトリでは1ユーザーあたり10ドルという価格設定になっており、(5ユーザーまでは無料ですが)中長期的にちょっと負担になるかもしれないなというのと、そこまで厳密にカバレッジを常に監視しなくていいのではと思うので活用するかは検討中です。
CIからS3等にHTMLをエクスポートし、レビュー時にチェックする
Codecovを使わずにCIによるフローに載せるのであれば、プルリクエスト時に自動テストが走った際にブランチ名のディレクトリでS3上にHTMLのレポートを全部吐き出し、レビュワーがチェックするといったGitHub Actionを組むことはできそうです。ジャストアイデアなので、実際難しければCodecovを使ったほうがいいかもしれません。
他のxdebugの機能を使う
Xdebugには、ステップ実行といった他の魅力的な機能もいくつかあるようなので、おいおい試したいと思います。
参考文献
- https://polidog.jp/2021/09/16/php-xdebug/
- https://xdebug.org/
- https://qiita.com/nazonohito51/items/0a499d2c1c01e70e972b
- https://qiita.com/ucan-lab/items/fbf021bf69896538e515
- https://zenn.dev/msksgm/articles/20211203-php-laravel-xdebug-mode-coverage
- https://qiita.com/bremen/items/d02eb38e790b93f44728
- https://qiita.com/koriym/items/29f81514706a39e3b7c1