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

7ivaypg9  于 2023-08-02  发布在  PHP
关注(0)|答案(5)|浏览(112)

我有一组复杂的PHPUnit测试,其中一些测试涉及到连接到世界各地的服务器,无论出于何种原因,有时会超时。
我不想在服务器超时时让测试失败,而是在实际将其标记为失败之前简单地重试该测试一次或多次。
我知道这不是解决我目前处境的最好办法。一个更好的解决方案是修复服务器。但是,这已经超出了我的控制范围。
所以,我真正想要的是一种方法,告诉PHPUnit对每个失败的测试用例重新测试X次,并且只有在每次都失败时才将其标记为失败。
有什么想法吗

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

ivqmmu1c

ivqmmu1c1#

**编辑:**根据下面的评论,这不再适用于PHPUnit 10+。

由于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;
    }
}

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

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

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

j8ag8udp

j8ag8udp2#

这不是对你问题的回答,但我还是要说:你的测试不应该包括远程资源(特别是当它们完全不受你控制的时候(不像本地镜像))。您应该将连接封装到单独的类中(例如Connection),在测试中模拟这些对象并处理远程主机将返回的静态响应。

ars1skjm

ars1skjm3#

与其连接到活动的服务器,难道不应该使用模拟对象和fixture,这样来自其他地方的响应就不会对测试产生影响吗?
您可以使用依赖注入来使用特定的HTTP客户端,该客户端将返回您告诉它的数据和响应代码(取决于您的代码是如何编写的)。理想情况下,单元测试应该独立于外部影响;你应该控制你测试的内容,例如,强制404或500错误应该是你测试的一个独立部分。
与其试图绕过非确定性测试,不如看看是否可以修改代码以启用模拟和测试夹具。
除此之外,您可能已经知道了,恐怕我不知道告诉PHPUnit允许测试失败的方法。这似乎完全违背了工具应该做的事情。

anhgbhbe

anhgbhbe4#

我不认为有一个支持,有人可以证明我错了,但在这种情况下我会感到惊讶。
我认为你可以做的是,不是马上在要检索的测试方法中Assert,而是循环X次并在成功时中断,在循环外Assert结果。
您已经考虑过这种简单的方法,其缺点是要向每个测试方法添加更多的代码。如果你有很多,它增加了维护负担。
否则,如果你想自动化更多,你可以实现一个PHPUnit_Framework_TestListener,在关联数组中保存失败测试的计数,并与测试运行进行比较。不知道这条路有多可行,但你可以给予。

ha5z0ras

ha5z0ras5#

您应该能够创建一个DB连接Assert,并在其他测试中将该测试“作为”您的DB连接来实现。在这个测试中,你可以根据需要尝试多次,并在X次尝试后返回false。

相关问题