PHPUnit Strict Mode - setUp() - Coverage

php, phpunit

Solution

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());
    }
}

Problem

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: - Changing `checkForUnintentionallyCoveredCode` to `false` obviously works, but I want to use this feature... - Using `processIsolation="true"` works too. I don't know why? - Adding `@covers` or `@uses` to `setUp()` doesn't work - Adding `@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...) - Different `phpunit`-Version: I tried this with `4.3` and `4.5` with same results - Different PHP-Setup: I tried this on a Win8 with XAMPP and a LinuxMint - same results Is 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 ```

Original source