Im using Phpunit. If I just run my tests with:
phpunit --log-junit output.xml
this runs within a second. But if I want a code coverage:
phpunit --coverage-html ./report --log-junit output.xml
then its very slow, the phpunit sends "Configuration read from *.xml" and it hangs for a minute, then it start executing the tests
By default, PHPUnit will evaluate the coverage of all files in your configured whitelist, even when you run PHPUnit for a single test.
If you have a lot files in your whitelist, this can add a LOT of time to the generation of the code coverage.
You can speed things up by configuring PHPUnit to generate code coverage only for the files you have written/execute tests for, by setting the addUncoveredFilesFromWhitelist
attribute to false
.
<phpunit>
<!-- ... -->
<filter>
<whitelist addUncoveredFilesFromWhitelist="false">
<!-- ... -->
</whitelist>
</filter>
</phpunit>
With this setting disabled, you should see that the resulting code coverage files only describe the files you ran the tests for.
Note that the PHPUnit documentation suggests addUncoveredFilesFromWhitelist
is false
by default, but on version 5.5 it appears to be true
by default.
Just to increment the last answer. Usually, it happens because PHPunit see all the files and you need to tell them to not do it, like this follow example:
Take a look to my filter node into phpunit.xml like this
<filter>
<whitelist>
<directory>../src</directory>
</whitelist>
</filter>
I need to add addUncoveredFilesFromWhitelist equal to false and add all of the files which I need to exclude, like this:
<filter>
<whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">../src</directory>
<exclude>
<directory>../vendor</directory>
<directory>../anotherpath</directory>
<directory>../src/Modules/*/Fixture</directory>
<file>../src/Modules/*/Bootstrap.php</file>
</exclude>
</whitelist>
</filter>
Pay attention to my exclude list where I exclude the "Fixture" directory and Bootstrap.php file for all modules
After did this simple changes my unit tests change from 10 minutes to 3 minutes, so enjoy :)
When running phpunit with code coverage, the thing that impacts the speed the most is the fact that for each test method, phpunit uses xdebug with XDEBUG_CC_UNUSED
and XDEBUG_CC_DEAD_CODE
, which checks for dead and unused code in every file that is touched during that particular test execution. This includes vendor classes, test classes, phpunit framework classes and any other classes outside of your whitelist. phpunit only actually cares about the subjects under test (or classes in your whitelist). I am in the process of tweaking code coverage to be smarter about running xdebug with the 2 mentioned flags on, so it only bothers checking out the dead and unused code of the files that phpunit cares about. You can check the progress here. https://github.com/sebastianbergmann/php-code-coverage/pull/387
This is normal behaviour.
Think about what PHPUnit is doing:
It's running your tests, tracking every execution of every line of code, then taking all that raw data (the number of times each line was executed) and building a report by reading your code and reformatting it as HTML, supplemented with all that execution data.
It's not surprising that it takes a long time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With