はじめに
この記事では、PHPUnitを使用したカバレッジレポートの生成に時間がかかるという問題について、その解決方法を紹介します。
対象読者
- PHPUnitを使ったことがある人
- カバレッジレポートの生成時間に課題を感じている人
テストカバレッジとは
テスト対象となるコードがどの程度テストされたかを定量的に示す指標のことです。テストの網羅性を確認するために使用され、主にコードの品質保証や潜在的な欠陥を見つける目的で活用されます。
どの程度テストを網羅していればいいかどうかは、サービスにより異なります。
あくまで一つの指標であり、盲目的にカバレッジの数字に固執せず適切にテストケースの設計をすることが重要です。
カバレッジを計測する目的は「テストが十分に網羅されていないコードを検出すること」であり、カバレッジの数値を高くすることだけに執着することは費用対効果が低い。
参考:https://qiita.com/maecha/items/d8bee8656b50ca6914eb
PHPUnitでのカバレッジレポート生成方法
PHPUnitではコードカバレッジドライバー(XdebugやPCOV)を使うことでカバレッジレポートが作成でき、どのファイルのテストが不足しているか確認することが可能です。
# htmlファイルで生成する例
./vendor/bin/phpunit --coverage-html coverage-result
生成が完了すると、実行環境の./coverage-result/index.htmlでレポートが確認できます。
※↑Xdebugを使ってブランチカバレッジまで生成した場合
ブランチカバレッジのレポート生成が重すぎる
私が所属するチームではXdebugを使ってカバレッジレポートの生成をしており、
最低でもブランチカバレッジを満たすようにテストを書く方針で進めています。
※カバレッジの種類については下記を参照してください。
ホワイトボックステストにおけるカバレッジ(C0/C1/C2/MCC)について
ただ、ブランチカバレッジのレポート生成は非常に重いです。
実装していくにつれレポートの生成時間が増加し、最終的に50分もかかるようになってしまいました。
↓ 実際の実行時間
./vendor/bin/phpunit --coverage-html coverage-result
............................................................... 63 / 431 ( 14%)
~ 省略 ~
..................................................... 431 / 431 (100%)
Time: 49:05.292, Memory: 382.50 MB
遅すぎるカバレッジレポートの生成。この問題を解消するために試したことを共有します。
1. 生成対象のテストを限定する
PHPUnitの標準コマンドで特定のフォルダやファイルに対象を限定することできます。
実行コマンド
#フォルダで絞る
./vendor/bin/phpunit tests/Unit/SampleFolder --coverage-html coverage-result
# ファイルで絞る
./vendor/bin/phpunit tests/Unit/SampleFolder/SampeTest.php --coverage-html coverage-result
生成対象が少なくなることでレポート生成の時間を短縮させることができました。
※実行対象ファイルが増えれば生成時間も増えていきます。
修正箇所の影響範囲が特定できている場合や、大規模な変更後に短時間で確認したい場合には使えそうでした。
2. PCOVを使う
PCOVはコードカバレッジ解析用のPHPの拡張ツールです。
高速かつ省メモリで動作することが特徴で、XdebugではなくPCOVを使うことでレポート生成時間の短縮が期待できます。
インストール
※方法は環境によって異なります
https://github.com/krakjoe/pcov/blob/develop/INSTALL.md
pecl install pcov
#php.iniファイルでpcovを有効化
zend_extension=pcov.so
pcov.enabled=1
実行コマンド
./vendor/bin/phpunit --coverage-html coverage
生成結果比較
↓445testsの2,990assertionsをラインカバレッジで生成した結果
ドライバー | 生成時間 | メモリ消費 |
---|---|---|
Xdebug | 43s | 84MB |
PCOV | 17s | 76MB |
Xdebugでの実行と比較するとメモリ消費が少なく、生成時間が短縮されました。
ただ、PCOVはブランチカバレッジの計測には対応しておらず、チームでの運用は断念しています。
ラインカバレッジのみ確認したいケースでは採用しても良さそうです。
3. phpcovを使って分割実行させる
phpcovとは、PHPのコードカバレッジを測定するためのコマンドラインツールです。
テストを分割実行して最終的にマージしてレポートを作成できる点が特徴です。
インストール
composer require --dev 'phpunit/phpcov'
実行コマンド
例)下記のフォルダ構成の場合
tests/
└── Unit/
├── Models/
│ ├── SampleUserTest.php
│ ├── SampleProductTest.php
│ └── SampleCategoryTest.php
├── Helpers/
│ ├── SampleStringHelperTest.php
│ └── SampleArrayHelperTest.php
└── Utils/
└── SampleDateHelperTest.php
# フォルダ単位でcovがファイルを生成
./vendor/bin/phpunit --coverage-php var/report/Models.cov tests/Unit/Models
./vendor/bin/phpunit --coverage-php var/report/Helpers.cov tests/Unit/Helpers
./vendor/bin/phpunit --coverage-php var/report/Utils.cov tests/Unit/Utils
# 分割した結果を統合して、全体のカバレッジレポートを生成
phpcov merge var/report --html var/coverage
生成結果比較
↓445testsの2,990assertionsをブランチカバレッジで生成した結果
ドライバー | 生成時間 |
---|---|
Xdebugのみ | 2,940s |
phpcov使用 | 196s |
分割実行でCPU負荷を分散できることが影響大きく、ブランチカバレッジレポート生成の実行時間を大幅に短縮することができました。(49分かかっていた処理が3分ほどに、、!)
まとめ
レポート生成時間の短縮において、ラインカバレッジのみでよければPCOV、ブランチカバレッジまで確認したいとなるとphpcovを使うのが良さそうでした。
必要に応じてフォルダやファイルを絞ったレポート生成をしていこうと思います。
今回はツールを使った解決法を書きました。今後メモリ負荷の軽減などテストコード自体の見直しもしていきたいです。テストコードの運用は始めたばかりなので、設計や運用は引き続き改善を目指していきます。
KIYOラーニング株式会社について
当社のビジョンは『世界一「学びやすく、分かりやすく、続けやすい」学習手段を提供する』ことです。革新的な教育サービスを作り成長させていく事で、オンライン教育分野でナンバーワンの存在となり、世界に展開していくことを目指しています。
プロダクト
- スタディング:「学びやすく・わかりやすく・続けやすい」オンライン資格対策講座
- スタディングキャリア:資格取得者の仕事探しやキャリア形成を支援する転職サービス
- AirCourse:受け放題の動画研修がついたeラーニングシステム(LMS)
KIYOラーニング株式会社では一緒に働く仲間を募集しています