I currently started using the strict
-Mode in PHPUnit, when I came across a Problem with the code-coverage:
If I use the setUp
-method to create a new instance of a my class the __constructor
-method is listed in the code-coverage as covered when i run the tests.
This is my test-setup:
phpunit.config.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd"
bootstrap="../vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestSize="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
checkForUnintentionallyCoveredCode="true"
processIsolation="false"
>
<testsuites>
<testsuite name="FooTests">
<directory suffix="Test.php">../tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="coverage/" higlight="true" showUncoveredFiles="true"></log>
</logging>
Foo.php
class Foo
{
protected $_bar;
public function __construct($bar)
{
$this->_bar=$bar; //Line 10
} //Line 11
public function getBar()
{
return $this->_bar;
}
public function getBar2()
{
return $this->_bar;
}
}
and the Test: FooTest.php
class FooTest extends \PHPUnit_Framework_TestCase
{
protected $_foo;
protected function setUp()
{
$this->_foo=new Foo(10);
}
public function testGetBar()
{
$this->assertSame(10, $this->_foo->getBar());
}
/**
* @covers Foo::getBar2
*/
public function testGetBar2()
{
$this->assertSame(10, $this->_foo->getBar2());
}
}
If I run the tests I get this result:
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.
Configuration read from C:\xampp\htdocs\unittest\build\phpunit.config.xml
.R
Time: 88 ms, Memory: 3.50Mb
There was 1 risky test:
1) FooTest::testGetBar2
This test executed code that is not listed as code to be covered or used:
- C:\xampp\htdocs\unittest\src\Foo.php:10
- C:\xampp\htdocs\unittest\src\Foo.php:11
OK, but incomplete, skipped, or risky tests!
Tests: 2, Assertions: 2, Risky: 1.
Generating code coverage report in HTML format ... done
As soon as I specify the @covers
on the test the problem appears.
Is this expected behavior?
Some things I tried:
checkForUnintentionallyCoveredCode
to false
obviously works, but I want to use this feature...processIsolation="true"
works too. I don't know why?@covers
or @uses
to setUp()
doesn't work@covers
that the setUp()
uses to the test does work, but the test doesn't actually cover the code. (If the tests get more complex, this seems to be a lot of writing...)phpunit
-Version: I tried this with 4.3
and 4.5
with same resultsIs there a way to remove the setUp()
code from the code-coverage and using @covers
on tests with methods they actually test?
Edit: This also affects inheritance. So if Bar
extends Foo
, and passes arguments on to Foo::__construct
that will be on the code-coverage too - which makes writing the @covers
for the __construct
a pain in the a**...
Additional info:
PHP 5.6.3 (cli) (built: Nov 12 2014 17:18:08)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
Code Coverage Analysis. Wikipedia: In computer science, code coverage is a measure used to describe the degree to which the source code of a program is tested by a particular test suite.
Code Coverage Percentage = (Number of lines of code executed by a testing algorithm/Total number of lines of code in a system component) * 100.
Since this question started to gain some momentum: Here is my kind-of-solution for the problem.
My unit-test (FooTest
) of Foo
will always use Foo
, therefore I add @uses Foo
to the class.
This is also important if protected
/private
functions are used by public
functions, because else you have to add each and every protected
/private
function to a test, if the class uses the function internally. I even think it is wrong if you are doing unit-tests, because a unit-test must not care about how the class does "stuff", it should only assert that a specific input results in a specific output.
(Additionally: The constructor should only do assignments, nothing else.)
After adding @uses
the error will disapear.
(You can add @covers Foo::_construct
to the class to have code-coverage of your constructor.)
/**
* @uses Foo
* (optional)@covers Foo::__construct
*/
class FooTest extends \PHPUnit_Framework_TestCase
{
protected $_foo;
protected function setUp()
{
$this->_foo=new Foo(10);
}
public function testGetBar()
{
$this->assertSame(10, $this->_foo->getBar());
}
/**
* @covers Foo::getBar2
*/
public function testGetBar2()
{
$this->assertSame(10, $this->_foo->getBar2());
}
}
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