仅在PHPUnit中需要时执行dataProviders?

时间:2016-12-09 09:24:33

标签: php phpunit

我的测试套件即使只是开始需要几分钟。这是因为数据提供程序在phpunit的启动时一次性执行,所有数据(数千个对象)都保存在内存中。

有没有办法在测试运行之前调用dataProviders,而是?我不在乎在屏幕上看到如此精确的进展。

由于

2 个答案:

答案 0 :(得分:3)

这需要一些重构,但我建议从测试方法中删除数据提供程序,而是在实际测试中对数据提供程序方法进行方法调用。

正如您已经知道的那样,来自PHPUnit的手册:

在调用setUpBeforeClass静态方法和第一次调用setUp方法之前执行所有数据提供程序。因此,您无法从数据提供程序中访问您在其中创建的任何变量。这是PHPUnit能够计算测试总数所必需的。

您应该将这些数据提供程序推送到您的测试方法可以临时调用的哑类中。

所以而不是

/**
 * @dataProvider additionProvider
 */
public function testAdd($a, $b, $expected)
{
    $this->assertEquals($expected, $a + $b);
}

/**
 * As you know this will be executed before any tests, as will all of them
 */
public function additionProvider()
{
    return [
        [0, 0, 0],
        [0, 1, 1],
        [1, 0, 1],
        [1, 1, 3]
    ];
}

在扩展PHPUnit\Framework\TestCase的测试基类中定义数据提供程序,将它们组织成逻辑组,并将测试类扩展掉。

class SomeDataProviderClass extends TestCase
{
    public function provideSomeData()
    {
        return [
            [0, 0, 0],
            [0, 1, 1],
            [1, 0, 1],
            [1, 1, 3]
       ];
    }
}


class AnActualTest extends SomeDataProviderClass
{
    public function testThatDependsOnSomeDataBeingProvided()
    {
        $data = $this->provideSomeData()
        // Use the data and do your test
    }
}

显然,考虑到你有多少测试它并不理想,但除了在整个地方都有很多@dataProvider注释之外,它的组织方式更好(大概是因为你没有给出任何我无法分辨的代码)。所有数据提供者方法都将按逻辑组织并且更易于维护,当然这应该可以使测试运行得更快。

唯一可能的缺点是,如果您的数据提供者从数据库等获取东西(再次,因为您没有发布我不知道的代码),因为多次调用相同的提供者函数将是每次数据库往返。但是,您可以轻松地缓存此类方法调用的返回值。

答案 1 :(得分:0)

@depends注释可以用作数据提供者之类的思考:

public function testAsDataProvider(): int
{
    return 2 * 2; // very expensive and long computations
}

/**
 * @depends testAsDataProvider
 */
public function testFoo($data)
{
    $this->assertEquals(4, $data);
}

/**
 * @depends testAsDataProvider
 */
public function testBar($data)
{
    $this->assertNotEquals(5, $data);
}

在此示例中,方法testAsDataProvider()将在其他测试之前执行一次,其结果将传递给testFoo()testBar()