仅在 PHPUnit 中需要时才执行 dataProviders?

Execute dataProviders only when needed in PHPUnit?

我的测试套件甚至需要几分钟才能开始。那是因为数据提供者是在 phpunit 启动时立即执行的,并且它们的所有数据(数千个对象)都保存在内存中。

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

谢谢

@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()

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

您已经从 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 注释更好地组织(大概;因为你没有给出任何我无法分辨的代码).所有数据提供程序方法都将按逻辑组织并更易于维护,当然这应该会使测试 运行 快很多。

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