phpunit:重用dataprovider

时间:2017-03-12 22:47:39

标签: iterator phpunit

我想针对整个文件集的内容运行多个测试用例。我可以使用数据提供程序加载我的文件,并为所有测试使用相同的提供程序,如下所示:

string result = String.Join("+delimiter+", fields);

显然,这意味着如果我有10个测试用例,每个文件加载10次。

我可以调整数据提供程序来加载所有文件并返回一个包含所有内容的大结构。但是,由于为每个测试单独调用提供程序,它仍然意味着每个文件被加载10次,此外它会同时将所有文件加载到内存中。

我当然可以将10个测试压缩成一个带有10个断言的测试,但是在第一个断言失败后它会立即中止,我真的想要报告文件中所有错误的内容。

我知道数据提供者也可以返回迭代器。但phpunit似乎为每个测试单独重新运行迭代器,仍导致每个文件加载10次。

有没有一种聪明的方法可以让phpunit只运行一次迭代器并将结果传递给每个测试,然后再继续?

1 个答案:

答案 0 :(得分:0)

测试依赖项

如果某些测试是依赖项,则应使用@depends注释来声明Test dependencies。依赖项返回的数据由声明此依赖关系的测试使用。

但是,如果声明为依赖的测试失败,则不会执行依赖测试。

静态存储数据

要在测试之间共享数据,setup fixtures statically是常见的。 您可以对数据提供者使用相同的方法:

<?php

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    private static $filesContent = NULL;

    public function filesContentProvider()
    {
        if (self::$filesContent === NULL) {
            $paths = glob(__DIR__ . '/files/*');

            self::$filesContent = array_map(function($path) {
                return [file_get_contents($path)];
            }, $paths);
        }
    }

    /**
     * @dataProvider filesContentProvider
     */
    public function test1($content)
    {
        $this->assertNotEmpty($content, 'File must not be empty.');
    }

    /**
     * @dataProvider filesContentProvider
     */
    public function test2($content)
    {
        $this->assertStringStartsWith('<?php', $content, 
                                      'File must start with the PHP start tag.');
    }
}

正如您所看到的,它不支持开箱即用。由于每个测试方法执行后销毁测试类实例,您必须将初始化数据存储在类变量中。