PHPUnit Strict Mode - setUp() - Coverage


PHPUnit Strict Mode - setUp() - Coverage

我目前开始使用 PHPUnit 中的 strict -Mode,当时我遇到了代码覆盖率问题:

如果我使用 setUp -方法创建 my 类的新实例,则运行测试时,__constructor -方法将列在代码覆盖率中。

这是我的测试设置:

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>

福.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;
    }
}

和测试: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());
    }
}

如果我运行测试,我会得到以下结果:

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

一旦我在测试中指定@covers,问题就会出现。

这是预期行为吗?

我尝试过的一些事情:

  • checkForUnintentionallyCoveredCode更改为false显然有效,但我想使用此功能...
  • 使用processIsolation="true"也有效。我不知道为什么?
  • setUp()添加@covers@uses不起作用
  • setUp()使用的@covers添加到测试中确实有效,但测试实际上并未涵盖代码。(如果测试变得更加复杂,这似乎是很多写作......
  • 不同的phpunit版本:我用4.34.5尝试了这个,结果相同
  • 不同的PHP设置:我在带有XAMPP和LinuxMint的Win8上尝试了这个 - 相同的结果

有没有办法从代码覆盖率中删除setUp()代码,并使用实际测试的方法在测试中使用@covers

编辑:这也会影响继承。因此,如果Bar扩展Foo,并将参数传递给Foo::__construct,这也将出现在代码覆盖率上 - 这使得为__construct编写@covers成为一种痛苦......

附加信息:

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

由于这个问题开始获得一些动力:这是我对这个问题的解决方案。

我的单元测试(FooTest(Foo将始终使用Foo,因此我在类中添加了@uses Foo

如果public函数使用 protected/private 函数,这一点也很重要,因为否则您必须将每个 protected/private 函数添加到测试中,如果类在内部使用该函数。我什至认为如果你在做单元测试是错误的,因为单元测试一定不关心类如何做"东西",它应该只断言特定的输入导致特定的输出。

(另外:构造函数只应执行赋值,而不执行其他

任何操作。

添加@uses后,错误将消失。

(可以向类中添加@covers Foo::_construct,以获得构造函数的代码覆盖率。

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

您已指定了 checkForUnintentionallyCoveredCode="true" 的严格覆盖范围。由于 PHPUnit 4.0 PHPUnit 具有以下行为:

处理无意中覆盖的代码

PHPUnit 4.0 可以选择对无意中覆盖的代码严格(严格>覆盖模式(。启用后,PHPUnit 将无法通过使用@covers注释并执行未使用@covers注释指定的代码的测试。

PHPUnit>= 6.0 上,将 beStrictAboutCoversAnnotation 设置为 false phpunit.xml

<phpunit
     // ....     
     beStrictAboutCoversAnnotation="false"
>
// ....

此外,你可以在没有 --strict-coverage 的情况下运行 phpunit

有关风险测试的详细信息:无意中涵盖的代码