有人可以解释为什么下面的函数没有被phpUnit完全覆盖? 或者更好的是,解释如何将其报告为完全覆盖?
function itDoesThingsToValue()
{
static $value = -1;
if ($value < 0) {
$value = 1978;
//Do some more stuff with $value
//But $value keeps being > 0
}
return $value;
}
XDebug代码覆盖率报告一次或多次调用此函数时所涵盖的所有行。
PHPUnit会在调用一次时报告这些行。
多次调用它(由于不同的PHPUnit测试),PHPUnit报告{}之间的行没有被覆盖。
我知道{}之间的行只因为静态变量$ value而执行一次,但imho执行的行应始终报告为覆盖,无论它们是否在以下调用中跳过(通过以下测试)。
答案 0 :(得分:1)
我运行了你的代码并同意,这是一种奇怪的行为,在最后}
显示一条不存在的行,因为没有覆盖(83%的覆盖率)。我在边缘情况下的PHPUnit documentation for Code Coverage中找到了以下内容:
// Because it is "line based" and not statement base coverage
// one line will always have one coverage status
if (false) this_function_call_shows_up_as_covered();
// Due to how code coverage works internally these two lines are special.
// This line will show up as non executable
if (false)
// This line will show up as covered because it is actually the
// coverage of the if statement in the line above that gets shown here!
will_also_show_up_as_covered();
// To avoid this it is necessary that braces are used
if (false) {
this_call_will_never_show_up_as_covered();
}
所以我将最后一个移到了返回线,它开始报告100%的覆盖率。
function itDoesThingsToValue(){
static $value = -1;
if ($value < 0) {
$value = 1978;
//Do some more stuff with $value
//But $value keeps being > 0
}
return $value;}
答案 1 :(得分:0)
我还不完全清楚,因为我不知道PHPUnit的来龙去脉,但情况就是这样......
在第一次单元测试期间调用我的类的构造函数时调用该函数。在这个测试中,我声明该函数被覆盖(使用@covers注释)。
在某个地方,我在数据提供者中再次调用此函数来测试另一个函数。
因为我认为我的函数已经过测试和覆盖(在构造函数测试中),所以应该保存它以在dataprovider中使用它。 实际上,这会导致报告的行未被覆盖。
所以我最好的猜测是在单元测试之前运行dataprovider函数。
修改强>
添加一些调试代码后,确实确认所有数据提供程序方法在任何测试*方法之前执行。
以下示例产生了我的问题:
public function setUp() {
//Echo the executed testmethod name and 'starting' time into the console.
echo $this->getName(), ' ', date('H:i:s'), chr(10), chr(13);
}
/**
* @covers MyClass::_construct
* @covers MyClass::myMethod
*/
public function testConstructor() {
//Do some stuff
}
public function myDataProvider() {
//Echo the 'starting' time of the data provider method in the console.
echo 'DataProvider started executing at', ' ', date(H:i:s), chr(10), chr(13);
$value = MyClass::myMethod; //This causes the lines not being covered
return [[$value + 1], [$value -1]];
}
/**
* @covers MyClass::AnotherMethod
* @dataprovider myDataProvider
*/
public function testSomethingElse {
//Do some stuff
}
控制台输出:
Testing started at 21:55 ...
DataProvider started executing at 21:55:46
PHPUnit 5.5.5 by Sebastian Bergmann and contributors.
testConstructor 21:55:47
testSomethingElse 21:55:47
我的解决方案是:
private $testClassValue;
/**
* @covers MyClass::_construct
* @covers MyClass::myMethod
*/
public function testConstructor() {
//Do some stuff
$this->$testClassValue = myClass::value;
}
public function myDataProvider() {
$value = $this->$testClassValue;
return [[$value + 1], [$value -1]];
}
/**
* @covers MyClass::AnotherMethod
* @dataprovider myDataProvider
*/
public function testSomethingElse {
//Do some stuff
}