当我遇到代码覆盖问题时,我目前开始在PHPUnit中使用strict
- 模式:
如果我使用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()
不起作用@covers
用于测试的setUp()
确实有效,但测试实际上并不涵盖代码。 (如果测试变得更复杂,这似乎是很多写作......)phpunit
- 版本:我使用4.3
和4.5
尝试了相同的结果有没有办法从代码覆盖中删除setUp()
代码,并在测试时使用@covers
实际测试的方法?
编辑:这也会影响继承。因此,如果Bar
扩展Foo
,并将参数传递给代码覆盖范围内的Foo::__construct
,那么就会为@covers
编写__construct
a **中的痛苦......
其他信息:
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
答案 0 :(得分:4)
由于这个问题开始获得一些动力:这是我对这个问题的解决方案。
Foo
的单元 - 测试(Foo
)始终使用 @uses Foo
,因此我添加了protected
到了班级。
如果private
函数使用public
/ protected
函数,这也很重要,因为否则您必须添加每个private
/ {{ 1}}函数测试,如果类在内部使用该函数。我甚至认为如果你进行单元测试是错误的,因为单元测试一定不关心类如何做“东西”,它应该只断言特定输入会产生特定的输出。 < / p>
(另外:构造函数应该只进行赋值,没有别的。)
添加@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());
}
}
答案 1 :(得分:2)
您已使用checkForUnintentionallyCoveredCode="true"
指定了严格的覆盖范围。由于PHPUnit 4.0 PHPUnit具有以下行为:
处理无意中涵盖的代码
PHPUnit 4.0可以选择严格关于无意中覆盖的代码(严格的&gt;覆盖模式)。启用后,PHPUnit将使用@covers注释的测试失败,并执行未使用@covers注释指定的代码。
答案 2 :(得分:0)
在 PHPUnit> = 6.0 上,将phpunit.xml
上的beStrictAboutCoversAnnotation设置为false:
<phpunit
// ....
beStrictAboutCoversAnnotation="false"
>
// ....
此外,您可以在不使用--strict-coverage的情况下运行phpunit
答案 3 :(得分:0)
我认为接受的答案不正确。它基本上说,该类中的任何内容都可以使用。可能是您想要的,也可能不是。具体来说,如果您要确保您的testGetBar2()
方法未使用其他代码,您将无法使用。
您可以做的是ignore您设置方法的作用。
/**
* @codeCoverageIgnore
*/
protected function setUp()
{
$this->_foo=new Foo(10);
}
这样,您在设置中输入的任何内容都不会算作经过测试的代码,但是会显示您专门介绍的所有内容。