【发布时间】:2015-04-20 12:58:40
【问题描述】:
当我遇到代码覆盖问题时,我目前开始在 PHPUnit 中使用 strict-Mode:
如果我使用setUp-方法创建我的类的新实例,__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>
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;
}
}
和测试: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"也可以。不知道为什么? - 将
@covers或@uses添加到setUp()不起作用 - 将
setUp()用于测试的@covers添加到测试中确实有效,但测试实际上并未涵盖代码。 (如果测试变得更复杂,这似乎是很多写作......) - 不同的
phpunit-Version:我用4.3和4.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
【问题讨论】:
-
通常建议构造函数做尽可能少的工作,事实上,如果可能的话,除了将参数分配给实例变量之外,它们不应该做任何事情。一个简单的构造函数实际上并不需要进行测试,因此它对代码覆盖率报告的影响应该并不重要。至于您的情况,您可以尝试简单地使用一个空的 setup() 方法并在每个测试用例中执行 $this object = new ObjectUnderTest() 。
-
@GordonM 我唯一要测试的是,依赖项(数据库、记录器等)的类型提示是否设置正确。 __construct 方法只做赋值。