PHPUnit - 自动重试失败的测试X次?

Mik*_*eC8 11 php phpunit integration-testing

我有一组复杂的PHPUnit测试,其中一些涉及连接到世界各地的服务器,无论出于何种原因,有时会超时.

当服务器超时时,我不想让测试失败,我只想在实际将其标记为失败之前重试该测试一次或多次.

现在,我知道这可能不是处理我手头情况的最好方法.一个更好的解决方案是修复服务器.但是,这是我现在无法控制的.

所以,我真正喜欢的是一种告诉PHPUnit重新测试每个失败的测试用例X次的方法,并且只有在每次失败时才将其标记为失败.

有任何想法吗?

编辑:你们中的许多人都提出了有用的建议,我没有这样做.我明白了,谢谢.但是,具体而言我要创建一个测试套件来测试整个系统的操作,包括远程服务器.我理解使用来自外部的"模拟"响应测试我的代码的某些部分的概念......但如果我的部分测试测试"完整堆栈",我也会在晚上睡得更好.

Dav*_*ess 11

由于PHPUnit不支持开箱即用的这种行为,因此您需要自己编写循环代码.而不是在每个需要它的测试中执行它,创建一个自定义测试用例基类(如果您还没有),它扩展PHPUnit_Framework_TestCase并提供该功能.

你可以得到花哨和覆盖testBare()以检查注释,例如@retry 5,循环那么多次,调用parent::testBare()和吞下除了最后一个之外的所有异常(或子集).

public function runBare() {
    // I'll leave this part to you. PHPUnit supplies methods for parsing annotations.
    $retryCount = $this->getNumberOfRetries();
    for ($i = 0; $i < $retryCount; $i++) {
        try {
            parent::runBare();
            return;
        }
        catch (Exception $e) {
            // last one thrown below
        }
    }
    if ($e) {
        throw $e;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建一个类似的辅助方法,该方法将重试次数和闭包/可调用作为参数,并从需要它的每个测试中调用它.

public function retryTest($count, $test) {
    // just like above without checking the annotation
    ...
        $test();
    ...
}

public function testLogin() {
    $this->retryTest(5, function() {
        $service = new LoginService();
        ...
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 基于这个答案的完整解决方案https://gist.github.com/makasim/989fcaa6da8ff579f7914d973e68280c (3认同)

Kin*_*nch 6

不完全是你的问题的答案,但无论如何我会说:你的测试永远不应该包括远程资源(特别是当它们完全不在你的手中时(与本地镜像不同)).您应该将连接封装到单独的类中(例如Connection),并在测试中模拟这些对象并使用静态响应,远程主机将返回.

  • 对于单元测试,这是正确的,但是对于自动验收测试,关于是否模拟外部服务仍然存在很多争论。我们选择不这样做,它可以增加测试的脆性。在这种情况下,重试可能会有所帮助。 (2认同)