我可以使用@depends依赖于使用@dataProvider的测试吗?

时间:2012-05-22 18:03:18

标签: php unit-testing phpunit

我有一个测试类,其中一个测试通过@dataProvider多次运行,另一个测试@depends在第一个方法上运行。但是,当我在应该传递给第二个测试的内容上调用var_dump时,它给了我一个可靠的NULL,这是我没想到的。

换句话说:这应该做什么:

<?php 
class DevicesTest extends PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider registerDataProvider
     */
    public function testRegister($device, $supposedResult)
    {
        //do a bunch of tests
        return array($device, $supposedResult);
    }

    public function registerDataProvider()
    {
        return array(array("foo", "foo"));
    }

    /**
     * @depends testRegister
     */
    public function testSaveDevicePreferences($deviceArr)
    {
        $this->assertNotEmpty($deviceArr);
    }
}
?>

3 个答案:

答案 0 :(得分:14)

在PHPUnit的当前版本(截至今天为5.4)中,它是可能的。

根据documentation

  

当测试从@dataProvider方法和@depends on的一个或多个测试接收输入时,来自数据提供者的参数将来自依赖测试的参数。来自依赖测试的参数对于每个数据集都是相同的。

这就是它的实际看法:

<?php

class DataProviderAndDependsCombinationTest extends AbstractUnittest{

    public function dataProviderForSomething()
    {
        return array(
            array(
                'someProvidedValue',
                'someOtherProvidedValue'
            )
        );
    }

    public function testToDependOn()
    {
        $this->assertTrue(true);
        return 'someDependedValue';
    }

     /**
     * @dataProvider dataProviderForSomething
     * @depends testToDependOn
     */
    public function testSomething($someProvidedValue, $someOtherProvidedValue, $someDependedValue)
    {
        $this->assertSame('someProvidedValue', $someProvidedValue);
        $this->assertSame('someOtherProvidedValue', $someOtherProvidedValue);
        $this->assertSame('someDependedValue', $someDependedValue);
    }
}

答案 1 :(得分:8)

通常情况下,@dataProvider用于多次运行测试,每个测试使用不同的数据集。它的存在是为了避免您在测试中编写循环代码,并允许不同的数据集单独通过或失败。

正如我在评论中所说,我相信PHPUnit将使用@depends @dataProvider,并且从您的示例中我的猜测是第二次胜出。另一种可能性是,使用数据提供程序的测试不能用作依赖项,因为PHPUnit不知道要选择哪个测试加数据集。

由于registerDataProvider返回单个数据集,您可以轻松地从测试本身调用它。这将允许@depends在没有@dataProvider的情况下在第二次测试中工作。假设testRegister需要修改$device和/或$supposedResult,这应该有效:

class DevicesTest extends PHPUnit_Framework_TestCase {
    public function testRegister() {
        list($device, $supposedResult) = $this->registerDataProvider();
        //do a bunch of tests
        //register a device in the DB
        return array($device, $supposedResult);
    }

    public function registerDataProvider() {
        return array("foo", "foo");
    }

    /**
     * @depends testRegister
     */
    public function testSaveDevicePreferences($data) {
        list($device, $supposedResult) = $data;
        // do stuff dependent on testRegister()
        $this->assertEquals($device, $supposedResult);
    }
}

如果第一次测试不需要修改这些变量,则只需从两次测试中调用registerDataProvider即可。请注意,PHPUnit不会在测试时将返回的数组与依赖项分离为依赖测试的参数,如数据提供程序机制所做的那样。这是因为它不知道返回的数组是多个参数而不是单个参数。

答案 2 :(得分:0)

我发现不,这是不可能的。然而,通过略微调整测试类,我已经实现了基本相同的结果,但是,依赖关系似乎丢失了,因为如果第一个测试失败,第二个测试很快就会运行:

<?php 
class DevicesTest extends PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider registerDataProvider
     */
    public function testRegister($device, $supposedResult)
    {
        //do a bunch of tests
        //register a device in the DB
        return array($device, $supposedResult);
    }

    public function registerDataProvider()
    {
        return array(array("foo", "foo"));
    }

    /**
     * @depends testRegister
     * @dataProvider registerDataProvider
     */
    public function testSaveDevicePreferences($device, $supposedResult)
    {
        // do stuff dependent on testRegister()
        $this->assertEquals($device, $supposedResult);
    }
}
?>