如何组织对一系列类似输入进行操作的测试?(How can I organize tests operating on a range of similar inputs?)

编程入门 行业动态 更新时间:2024-10-11 23:20:36
如何组织对一系列类似输入进行操作的测试?(How can I organize tests operating on a range of similar inputs?)

给出一组测试数据文件

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个断言,并且我失去了以下好处:

我无法知道哪些测试数字失败/通过,因为测试在第一次失败的断言时停止。 在第二次执行时,我不能只运行失败的测试。 我无法选择特定的测试编号x - 以调试模式运行

在添加更多代码以获得此优势之前,是否有更好的解决方案? 在这种情况下, phpunit功能可以提供哪些帮助?

Given a set of test data files

test001.txt test002.txt etc.

and expected results data files

expected001.txt expected002.txt etc.

I am using phpunit to test the data processing functionality:

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); }

The process code is exactly the same for all pairs of test data files and corresponding result data files.

Therefore, to apply the test on all the files I can make a loop:

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); } }

However, this way I have 213 assertions in one test, and I loose the following benefits:

I cannot know what tests numbers failed/passed, since the test stops for first failed assertion. On the second execution, I cannot run only the failed tests. I cannot choose a specific test number x - to run in debug mode

Before adding more code to get this benefits, is there a better solution? What phpunit features can help in this case?

最满意答案

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

/** * @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); }

供参考,请参阅:

https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers http://php.net/manual/en/language.generators.syntax.php http://php.net/manual/en/function.array-map.php http://php.net/manual/en/function.array-combine.php

You can use a data provider instead:

/** * @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 , ]; } }

If you can't use generators yet, adjust the data provider to:

/** * @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); }

For reference, see:

https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers http://php.net/manual/en/language.generators.syntax.php http://php.net/manual/en/function.array-map.php http://php.net/manual/en/function.array-combine.php

更多推荐

本文发布于:2023-08-06 09:16:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1446872.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:类似   操作   组织   测试   系列

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!