我有一个测试方法依赖于另一个本身在PHPUnit中使用数据提供程序的方法:
/**
* @dataProvider getFields
*/
public function testCanDoSomeStuff($parm1, $parm2) {
$result = my_func($parm1, $parm2);
$this->assertNotNull($result);
return $result;
}
/**
* @depends testCanDoSomeStuff
*/
public function testCanDoSomeMoreStuff($result) {
$this->assertNotNull($result);
}
我还有getFields()
数据提供程序功能,无需在此处显示。
依赖于数据提供者传递的第一个测试 - $result
非空。
我希望测试结果将作为$result
参数传递给依赖测试。但是,testCanDoSomeMoreStuff
函数会收到NULL
参数,测试失败。
更新
这个简单的测试用例演示了这个问题:
class MyTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider myFunc
*/
public function testCanDoSomeStuff($value) {
$this->assertNotNull($value);
return $value;
}
/**
* @depends testCanDoSomeStuff
*/
public function testCanDoSomeMoreStuff($value) {
$this->assertNotNull($value);
}
/**
* Data provider function
*/
public function myFunc() {
$values = array('22');
return array($values);
}
}
作为现在的解决方法,我已将结果存储在测试之间的静态属性中。
答案 0 :(得分:2)
如果$result
中的testCanDoSomeStuff()
确实不是null
,那么此 应该。
为了区别对待,首先尝试在没有数据提供者的情况下简化它,如下所示:
class StackTest extends PHPUnit_Framework_TestCase {
public function testCanDoSomeStuff() {
$result = true;
$this->assertTrue($result);
return $result;
}
/**
* @depends testCanDoSomeStuff
*/
public function testCanDoSomeMoreStuff($result) {
$this->assertNotNull($result);
}
}
测试这个应该导致类似......
~>phpunit test.php
PHPUnit 3.6.11 by Sebastian Bergmann.
..
Time: 1 second, Memory: 3.25Mb
OK (2 tests, 2 assertions)
现在添加数据提供程序,将我的简单变量替换为您的函数,然后再次测试它。
如果此结果不同,var_dump
变量$result
在您将其返回到测试用例testCanDoSomeStuff()
之前。如果不是null
,bug the behaviour。
答案 1 :(得分:2)
问题是几个因素的结果:
<name> with data set #<x>
。@depends
注释不接受多个单词。有一个hacky解决方法:覆盖TestCase::getDataSetAsString
以返回注释将接受的名称。这有点问题,因为所需的TestCase
字段是私有的,但是使用PHP 5.3.2+可以解决这个问题。
重要说明:很遗憾,您无法让每个数据行执行相关测试 - 只有一个特定行。如果您的数据提供者只返回一行数据,这不是问题。
以下是带有示例测试的代码。请注意,您不必为数据行命名。如果您不使用'foo'
密钥,请将@depends
更改为testOne-0
。
class DependencyTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider data
*/
public function testOne($x, $y) {
return $x + $y;
}
public function data() {
return array(
'foo' => array(1, 2),
);
}
/**
* @depends testOne-foo
*/
public function testTwo($z) {
self::assertEquals(3, $z);
}
protected function getDataSetAsString($includeData = false) {
if (!$includeData && $this->getPrivateField('data')) {
return '-' . $this->getPrivateField('dataName');
}
return parent::getDataSetAsString($includeData);
}
private function getPrivateField($name) {
$reflector = new ReflectionProperty('PHPUnit_Framework_TestCase', $name);
$reflector->setAccessible(true);
return $reflector->getValue($this);
}
}
显然,这不是一个长期的解决方案。对于来自接收数据的方法的每个测试结果,可以使依赖测试运行一次会更好。您可以向PHPUnit提交功能请求或拉取请求。
答案 2 :(得分:2)
我还预计所描述的问题会起作用,经过一些研究后,我发现这不是一个错误,而是一个预期的,没有记录的行为。依赖测试不知道提供者返回的数据集,这就是测试参数为空的原因。
来源:https://github.com/sebastianbergmann/phpunit/issues/183#issuecomment-816066
在测试执行之前计算@dataProvider注释。基本上,预测试阶段为数据提供者提供的每组参数创建测试方法。 @depends取决于基本上是数据驱动测试的原型,所以在某种程度上@depends是不存在的(未执行的测试)。
另一种思考方式是,如果提供者提供了多组参数。 PHPUnit会生成那么多的testDataProvider方法,但是没有那么多的testDataReceiver方法,因为在测试阶段没有针对预测试阶段的@dataProvider方法。
但是,您可以在同一测试方法上使用@depends和@dataProvider。请注意使参数顺序正确,尽管在这种情况下可能没有第一个参数。
基本上,当数据集有多行时,您应该使用数据提供程序。但是,您始终可以同时使用@depend
和@dataProvider
来实现大致相同的行为。