如何在PHPUnit中重复运行测试?

8
我知道有“--repeat”选项,但我更愿意在测试和每个测试中定义重复。在我的单元测试中,有些测试我不想重复,有些测试我想要比其他测试更多地重复。
我在考虑:
protected function tearDown() {
  if (test has not been ran 3 times) {
      $this->runTest(); // Re-run the test
  }
}

这个好像不起作用,$this->run() 也是一样。我看了PHPUnit源代码,但不太确定。我猜它在检查测试状态,如果已经运行过则拒绝再次运行。


我也想找到一个解决方案。@Gordon - 我的情况是,我正在通过套接字连接(thrift:php)测试服务。可能会发生测试失败仅因为网络过载,这实际上并不意味着...在超时异常的情况下,我想重新运行测试,以便它通过或抛出任何其他错误/异常。 - ducin
@tkoomzaaskz 你不能模拟远程端点吗?或者增加超时时间吗? - Gordon
@Gordon,我不能增加超时时间,因为我需要修改外部服务的设置,而我不想这样做。您能解释一下模拟远程端是什么意思吗?如果您的意思是让我使用模拟对象而不是真实服务,那行不通,因为我们正在测试服务和服务-PHP通信。所以服务必须是一个真实实例。 - ducin
@tkoomzaaskz 是的,这就是我所说的,也是 PHPUnit 手册中建议的:“当您的应用程序与 Web 服务交互时,您希望在不实际与 Web 服务交互的情况下对其进行测试。” 当您针对真实服务进行测试时,这不是单元测试。 - Gordon
@tkoomzaaskz 你可以使用Selenium进行端到端测试,但一般情况下我建议不要进行测试。 - Gordon
显示剩余3条评论
7个回答

17

PHPUnit 在命令行运行器中有一个重复选项。对于重复 3 次的测试,它的工作原理如下:

PHPUnit在命令行运行器中有一个重复选项。对于重复3次的测试,它的工作原理如下:

phpunit --repeat 3 myTest.php

我认为这只在10版本之前有效。 - Marshall Davis
我认为这仅适用于10版本之前。 - Marshall Davis
1
@MarshallDavis 是的,它已经从版本10中移除了。这里是一个快速解决方案:https://github.com/sebastianbergmann/phpunit/issues/5174#issuecomment-1510002606 - Clément Baconnier

6
这样做有点绕,但这是我能想到的最简洁的方法:
/**
 * @dataProvider numberOfTests
 */
public function test()
{
    // Do your test
}

public function numberOfTests() 
{
    for ($i = 0; $i < 100; $i++) {
       yield [];
    }
}

这样做的好处是对于循环的每次调用,setUp和tearDown方法都将被运行。

这是一个很好的解决方案,因为设置和拆卸方法会在每次测试用例调用时运行。 - Tomeh

2

运行测试不仅仅是调用setUpruntearDown方法。首先,每个测试方法都会在一个新的测试实例上运行。别忘了使用@dataProvider和其他注解、代码覆盖率等等。你真的不想这样做。

对于极少数情况下你绝对需要它,可以在测试方法中编写循环。


1
根据@reusen提到的,我们有以下指令。
phpunit --repeat 3 myTest.php

但是这个功能已经被删除并且没有计划重新实现。至少,目前不会。

目前有这个解决方法

while php vendor/bin/phpunit tests/ExampleTest.php --stop-on-failure; do echo; done

0

我认为你需要退一步,创建一个运行你的测试的测试!

你需要一个循环,大致如下:

$myTest = \my\test\class();
foreach($iterations){
    $myTest->setup();
    $myTest->doTestyStuff();
    $myTest->tearDown();
}

你发布的代码无法正常工作,因为每次测试运行时都需要运行设置和拆卸。


我把它放在tearDown里,因为tearDown在每个测试之后都会运行。这就是我考虑创建循环的方式。我将通过检查静态迭代器或其他东西来打破循环。我认为你上面提出的建议我可以从中得到启示,但我正在尝试运行每个测试X次,并不是每个测试都需要运行超过一次或相同次数。 - velo9

0
如果您使用终端鱼,您可以运行。
for i in seq(seq 10)                                                                                                                                          
    sail artisan test --filter MyControllerTest
end

-1

用do-while循环不能实现这个吗?

protected function tearDown() {
    $i = 0;
    do {
        $this->runTest(); // Re-run the test
        $i++;
    } while($i < 3);
}

重复并不是我的问题,我可以很容易地解决。问题在于调用$test->runTest()没有任何作用。另外,由于tearDown在每个测试之后被调用,你的代码假设$test->runTest()有效会导致它进入无限循环。 - velo9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接