如何组织对一系列类似输入进行操作的测试?

时间:2017-08-28 18:56:25

标签: php phpunit

给出一组测试数据文件

  • test001.txt
  • test002.txt

和预期结果数据文件

  • expected001.txt
  • expected002.txt

我正在使用phpunit来测试数据处理功能:

public function test001()
{
    $fn = "test001.txt";
    $data = file_get_contents($fn);

    // code to perform the test, and create $processedData from  $data

    $fn = "expected001.txt";
    $expestedData = file_get_contents($fn);

    $this->assertEquals($expestedData, $processedData);
}

所有测试数据对和相应的结果数据文件的过程代码完全相同。

因此,要对所有文件应用测试,我可以进行循环:

public function test001to213()
{
    for ($k = 0; $k < 213; $k++) {
        $fn = "test".sprintf('%03d', $k).".txt";
        $data = file_get_contents($fn);

        // data process code to create $processedData from $data

        $fn = "expected".sprintf('%03d', $k).".txt";
        $expectedData = file_get_contents($fn);

        $this->assertEquals($expectedData, $processedData);
    }
}

然而,这样我在一次测试中就有213个断言,并且我失去了以下好处:

  1. 我不知道哪些测试号码失败/通过,因为测试在第一次失败的断言时停止。
  2. 在第二次执行时,我无法只运行失败的测试。
  3. 我无法选择特定的测试编号x - 以调试模式运行
  4. 在添加更多代码以获得此优势之前,是否有更好的解决方案? 在这种情况下,phpunit功能可以提供哪些帮助?

1 个答案:

答案 0 :(得分:4)

您可以改为使用数据提供者:

/**
 * @dataProvider providerFilenames
 *
 * @param string $testFilename
 * @param string $expectedFilename
 */
public function testContent($testFilename, $expectedFilename)
{
    $data = file_get_contents($testFilename);

    // code to perform the test, and create $processedData from  $data
    $processedData = '';

    $expectedData = file_get_contents($expectedFilename);

    $this->assertEquals($expectedData, $processedData);
}

/**
 * @return \Generator
 */
public function providerFilenames()
{
    for ($key = 0; $key < 213; ++$key) {
        $testFilename = sprintf(
            'test%03d.txt',
            $key
        );

        $expectedFilename = sprintf(
            'expected%03d.txt',
            $key
        );

        /**
         * by yielding with a name here, it's easier to tell which set failed
         */
        $name = sprintf(
            'this is set %03d',
            $key
        );

        yield $name => [
            $testFilename,
            $expectedFilename ,
        ];
    }
}

如果您还不能使用生成器,请将数据提供程序调整为:

/**
 * @return \Generator
 */
public function providerFilenames()
{
    $keys = range(0, 213);

    $names = array_map(function ($key) {
        return sprintf(
            'this is set %03d',
            $key
        );
    }, $keys);

    $data = array_combine(
        $names,
        $keys
    );

    return array_map(function ($key) {
        $testFilename = sprintf(
            'test%03d.txt',
            $key
        );

        $expectedFilename = sprintf(
            'expected%03d.txt',
            $key
        );

        return [
            $testFilename,
            $expectedFilename
        ];
    }, $data);
}

供参考,见:

相关问题