Phpunit coverage: what is the difference between 'addUncoveredFilesFromWhitelist' and 'processUncoveredFilesFromWhitelist' options?
A quick peek in the source code of php-code-coverage
package on GitHub reveals the truth:
- if
addUncoveredFilesFromWhitelist
isFALSE
then the code coverage contains information about the files that were loaded and executed (only the lines that contain code are included);
the value ofprocessUncoveredFilesFromWhitelist
is ignored in this case; - if
addUncoveredFilesFromWhitelist
isTRUE
then the files from the white list that were not loaded and executed will be included in the code coverage too:- if
processUncoveredFilesFromWhitelist
isFALSE
then the files are not processed in any way; all their lines will appear in the code coverage as not being executed, even the empty lines and the lines that contain only comments; this is the quick and dirty way to get the things done; - if
processUncoveredFilesFromWhitelist
isTRUE
then the files are included and XDebug's code coverage functionality is used (the same as for the files that actually ran) to put into the report only the lines that contain code; this is the slow hard-working way.
- if
The default value for addUncoveredFilesFromWhitelist
is TRUE
and for processUncoveredFilesFromWhitelist
is FALSE
. This means the files from the whitelist that were not covered (because they didn't run) are included in the report using the quick way and their coverage report, while exact (0%
), is computed using a total number of rows slightly bigger than the real one.
However, since 0
out of anything is still 0%
, it think this is the best way to include the uncovered files in the report.
How to add uncovered files to PHPUnit code coverage report of the Yii application
Why this is happening:
PHPUnit will require
/ include
all files in the white-listed if you tell it do addUncoveredFilesFromWhitelist="true"
.
If those files contain executable code it will be executed and you are seeing the results of the arising issues.
What to do
- Exclude all files with executable code from the whitelist
It's a little trouble but it works
- Fix your include paths so the include/require calls don't break anything
I have no real clue as to WHY those errors pop up but it seems to be an include path issue? The framework should have a way of resolving that I'd say.
- PHPUnit 3.7 will offer an "generate coverage but not via include" mode that looks at the files and "guesses" the executable lines for you.
Why won't PHPUnit code coverage report functions that aren't called?
This appears to be an ongoing bug with XDebug and PHP 7.0, as covered in this issue: https://github.com/sebastianbergmann/php-code-coverage/issues/411 So, it should be working as I expect and there's nothing incorrect about my setup. Guess I'll just have to wait until the underlying cause (in XDebug) is found and fixed. Until then, the thread notes that turning on process isolation is a work-around.
Configuring phpStorm and XML for phpUnit 7 (remote) Coverage
I’ve manage to solve all the problems I had. I’ve used some of the informations provided in the links I’ve pointed above.
First of all
Include errors
PhpUnit xml uses directive includePath, which in my case looked like this:
<php>
<includePath>/var/www/html/phpUnit</includePath>
</php>
Generally at this point the problem is with… existence of includePath in xml file. This attribute changes the inclusion path.
So lets say that You got project structure like that:
- dir: Classes
–- dir: A
–-- file: A.php class: A (extends B)
–- dir: B
–-- file: B.pphp class: B
-file: index.php
So from the look of file A.php You would need to include B.php like that:
../B/B.php
Since the working directory is
/var/www/html/phpUnit/Classes/
But now since You’ve set up inclusion path to:
var/www/html/phpUnit
File A, tries to load file B from the perspective of phpUnit folder, and it’s kinda looking for file in:
var/www/html
Not having this directive is not solving the problem as phpUnit seems to use some other default path.
I’ve solved this problem by changing the way I include files in project:
Just instead using:
include_once '../Interfaces/BasicCalculationsInterface.php';
I’ve started doing it like this:
include_once __DIR__.'/../Interfaces/BasicCalculationsInterface.php';
This way:
- Single files tests work fine
- Project itself works fine
- phpStorm detects methods, classes etc in included file
- Group tests work well too
Writing file index.html permission denied
I’ve stumbled upon this problem as well. This actually is some kind of phpStorm issue, which I don’t know how to solve permanently but I’ve dealt with it for the xml file from which I can run all my tests.
Basically phpStorm added some default configurations for executed tests.
In menu go to
Run/Edit Configurations
Take a look at field Test Runner options.
In my case phpStorm added
--coverage-html /
Everything would be fine, but I use Ubuntu on laptop as remote host, and phpStorm tries this way to create files in / directory for which there is no writing permission. Changing this to some writeable folder or removing this line solved the problem.
And that’s all, this is how my xml file looks like at this point (just in case someone would like to have something to look at)
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="phpunit.xsd"
verbose="true">
<filter>
<whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">/var/www/html/phpUnit</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="/var/www/html/phpunit/coverage.xml" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-html" target="/var/www/html/phpUnit/phpStormCoverageTest" lowUpperBound="35"
highLowerBound="70"/>
</logging>
<testsuites>
<testsuite name="allTests">
<directory suffix="Test.php">/var/www/html/phpUnit/Tests</directory>
</testsuite>
</testsuites>
</phpunit>
Preview of working html/phpStorm coverage
Difference between assertEquals and assertSame in PHPUnit?
I use both sporadically, but according to the docs:
assertSame
Reports an error identified by
$message
if the two variables$expected
and$actual
do not have the same type and value."
And as you can see in the example below the above excerpt, they are passing '2204'
and 2204
, which will fail using assertSame
because one is a string
and one is an int,
basically:
'2204' !== 2204
assertSame('2204', 2204) // this test fails
assertEquals
"Reports an error identified by $message if the two variables $expected and $actual are not equal."
assertEquals
does not appear to take datatype into consideration so using the above example of 2204
:
'2204' == 2204
assertEquals('2204', 2204) // this test passes
I just ran some unit tests against the above examples, and indeed they resulted in documented behavior.
Related Topics
Yii2 Global Filter/Behavior to Force User to Authenticate First
PHP Loop: Add a Div Around Every Three Items Syntax
Why Can't I Overload Constructors in PHP
Mssql Query Issue in PHP and Querying Text Data
Creating a Secure Login Using Sessions and Cookies in PHP
PHP JSON Encode Output Number as String
Best Way to Do a Weighted Search Over Multiple Fields in MySQL
Pass PHP Variable to Bootstrap Modal
JSON_Encode Produce JSON_Error_Utf8 from Mssql-Select
Utf8 Filenames in PHP and Different Unicode Encodings
How to Format Numbers to Have Only Two Decimal Places
How to Expire PHP Session If User Is Inactive for 15 Mins
PHP Warning:Mysqli_Num_Rows() Expects Parameter 1 to Be MySQLi_Result, Object Given