Speed up PHPUnit Code Coverage Analysis
Updated on 2019–06–23.
As a reference, here are my results of running the test suites of three sample projects:
As you can see, activating the code coverage analysis multiplies the time needed to run the test suites. Those are just examples of course, and depending on the size and complexity of your project and its tests you may obtain completely different results. Nevertheless, execution time will increase, sometimes to the point where your CI platform will time out before the end of the analysis.
In this article, we will take a look at three quick ways of speeding up the code coverage collection: first by optimizing xdebug usage, then by replacing it with an alternative code coverage driver (phpdbg and pcov).
1. Whitelist filtering with xdebug
PHPUnit provides a whitelist configuration option to narrow down the coverage report to a set of files or directories. By default, PHPUnit handles this whitelist filter directly, but this task can also be delegated to xdebug itself (2.6+), resulting in a great improvement of the code coverage data collection.
This can be done in two simple steps: first generate the xdebug filter script using PHPUnit, then include it using the prepend option of the test runner.
# dump filter file
$ php vendor/bin/phpunit --dump-xdebug-filter build/xdebug-filter.php# run the test suite
$ php vendor/bin/phpunit --prepend build/xdebug-filter.php --coverage-html build/coverage-report
2. Replacing xdebug with phpdbg
The second solution is to replace xdebug with another coverage data collector. As you may know, PHP 5.6+ includes its own debugger: phpdbg. And lucky for us, PHPUnit is compatible with it.
# run the test suite
$ phpdbg -qrr vendor/bin/phpunit --coverage-html build/coverage-report
You can find more information in the articles Generating Code Coverage with PHPUnit and phpdbg and Phpdbg Is Much Faster Than Xdebug For Code Coverage.
Impressive results ! But as you can see, memory consumption rises drastically with phpdbg. Although it might not be a problem when running tests on a development machine or on a self-hosted CI platform, it may become problematic on some SaaS CI platforms with limited resources.
3. Using PCOV as the code coverage driver
PCOV is a new code coverage driver released in 2019 by Joe Watkins. PHPUnit 8 has native support for it, but it can also be used with older versions (see the pcov-clobber repository). Thanks to Swashata Ghosh for his tweet and the discussion that followed for pointing it out !
# install the extension
$ pecl install pcov# run the test suite
$ php -d pcov.enabled=1 vendor/bin/phpunit — coverage-html=var/coverage-report
PCOV seams to be the clear winner right now ! Execution time is faster than phpdbg, and memory consumption is lower than xdebug. You will have to be able to install the extension on your CI platform to benefit from it, but it’s definitely worth a try !
I would like to thank the authors of all libraries cited in this article, including Sebastian Bergmann for PHPUnit, Derick Rethans for Xdebug, Joe Watkins for both Phpdbg and PCOV, and all the contributors for their hard work and everything they bring to the PHP community.