php7 + phpdbgで高速カバレッジ出力
先日は、今私が関わっているプロジェクトのphpのバージョンを挙げた際のTipsについて投稿しました。
http://blog.matchingood.com/entry/2017/03/09/202011blog.matchingood.com
今日は、php7にバージョンアップしたことによって可能になった、phpdbgによるコードカバレッジ出力について書きたいと思います。
phpdbgとは
phpdbgは、phpのデバッガです。デバッガというとphpの場合似たようなものとしてxdebugもありますが、xdebugはあくまでphpの拡張モジュールであって、その恩恵を最大限に受けるにはIDEが必要不可欠です。
一方、phpdbgは端末上での逐次実行やブレークポイントの設定など、デバッガとしての実行を端末環境で行うことができます。C言語に馴染みがある人ならgdbライクだというとわかっていただけると思います。
phpdbgはphp5.6からphpのコアモジュールとして採用されており、phpがインストール済みなら既にインストールされています。
今回はphpdbgのデバッガとしての使用についてはひとまず置いておいて、このphpdbgを用いたカバレッジの出力についてご紹介したいと思います。
今までのコードカバレッジの出力
現在私が関わっているプロジェクトでは、CIでのテストの際にコードカバレッジを出力しています。PHPUnitを用いている場合は以下のようなコマンドです。
/path/to/phpunit --coverage-html=$CIRCLE_ARTIFACTS
これによって、$CIRCLE_ARTIFACTS
の表すディレクトリにコードカバレッジがhtmlで出力されます。しかし、これがとても重い…
これまでのプロジェクト上のCI上のテスト(カバレッジ出力込)の実行時間について、過去の記録を調べてみました。CIはCircleCIを利用しています。
environment | assertions | time |
---|---|---|
php5.6 + phpunit 4.8.29 | 726 | 8m35s |
php7.0 + phpunit 4.8.29 | 724 | 2m56s |
php7.0 + phpunit 5.7.15 | 692 | 3m04s |
php5.6時代は700程度のアサーションでも8分以上かかっています。それに対してphp7恐るべし…!php5.6に比べて約3倍の高速化です。phpunitのバージョンアップはLaravel5.4へのバージョンアップの際に行いましたが、これについてはあまり関係していなさそうです(むしろ遅くなってる?)
とはいえ、これらのテストはカバレッジを出力しなければ、どれも30秒程度で終わります。つまり、CIでのテストを高速化するならこのカバレッジ出力の部分を高速化したい!ということになります。これを叶えるのがphpdbgです。
phpdbgを用いたコードカバレッジ出力
従来のカバレッジ出力では、ドライバとしてxdebugを利用しています。このドライバをphpdbgに変更するには、先ほどのコマンドの先頭にphpdbg -qrr
をつけるだけです。
phpdbg -qrr /path/to/phpunit --coverage-html=$CIRCLE_ARTIFACTS
phpdbgはphpのコアモジュールなので、phpにPATHが通っているならばphpdbgも通っていると思われるので、パスは省略しています。
phpdbgのコマンドオプションの説明についてはGoogle先生にお任せしますが、ここでの-qrr
は、「起動時のタイトル・バージョン表示を省略し、引数に指定されたスクリプトを即時実行した後、phpdbgを終了する」という意味になります。
では、phpunitによるテスト+phpdbgによるカバレッジ出力の結果を、先ほどの結果と合わせて見てみましょう。
environment | assertions | time |
---|---|---|
php5.6 + phpunit 4.8.29 | 726 | 8m35s |
php7.0 + phpunit 4.8.29 | 724 | 2m56s |
php7.0 + phpunit 5.7.15 | 692 | 3m04s |
php7.0 + phpunit 5.7.15 with phpdbg | 682 | 37s |
なんと軽々と1分を切っていきました。すさまじい速さです…
全体としても2分以上の短縮ができました。CIの高速化は熱心に取り組むにはややハードルの高いissueですが、この程度の変更で短縮できるならとても良いですね!
注意事項
phpdbgについては、php5.6からコアモジュールとして公式に配布されていますが、カバレッジの出力に関してはphp7からのサポートとなります。これについては、PHPUnitがカバレッジ出力に利用しているPHP_CodeCoverageというコンポーネントの要件に依存しているためです。
最後に
コードカバレッジの出力をphpdbgを通して行うことで、CIの時間を2分以上早めることができました!導入も手軽なので、php7を用いたプロダクトでカバレッジ出力がしたいのならば是非おすすめしたい方法です!