keboola/phpunit-retry-annotations

用于在PHPUnit中重试测试方法和类的特性

v0.5 2024-03-08 09:32 UTC

This package is auto-updated.

Last update: 2024-09-08 10:43:02 UTC


README

用于在PHPUnit中重试测试方法和类的特性。

安装

composer require --dev keboola/phpunit-retry-annotations

配置重试次数

默认重试次数设置为3,如果您想为所有测试更改默认的重试次数,请将此库中的phpunit-retry.xml.dist文件复制粘贴到应用程序的根目录中,并更改baseRetryCount的值。

使用指定的重试次数进行重试

/**
 * @retryAttempts 2
 */
class MyTest extends PHPUnit\Framework\TestCase
{
    use PHPUnitRetry\RetryTrait;

    public function testSomethingFlakeyTwice()
    {
        // Retry a flakey test up to two times
    }

    /**
     * @retryAttempts 3
     */
    public function testSomethingFlakeyThreeTimes()
    {
        // Retry a flakey test up to three times
    }
}

注意:“尝试次数”表示测试重试的次数。为"@retryAttempts"提供一个值为0的值没有效果,并且不会重试。

重试直到经过特定的时间长度

/**
 * @retryForSeconds 90
 */
class MyTest extends PHPUnit\Framework\TestCase
{
    use PHPUnitRetry\RetryTrait;

    public function testSomethingFlakeyFor90Seconds()
    {
        // retries for 90 seconds
    }

    /**
     * @retryForSeconds 1800
     */
    public function testSomethingFlakeyFor30Minutes()
    {
        // retries for 30 minutes
    }
}

配置重试条件

只对某些异常进行重试

默认情况下,当抛出除PHPUnit\Framework\IncompleteTestErrorPHPUnit\Framework\SkippedTestError之外的任何异常时,都会进行重试。

由于您可能并不总是想要重试,您可以配置测试只在某些条件下进行重试。例如,只有当您的测试抛出特定的异常时,您才进行重试。

/**
 * @retryAttempts 3
 * @retryIfException MyApi\ResourceExhaustedException
 */

可以对多个异常进行重试。

/**
 * @retryAttempts 3
 * @retryIfException MyApi\RateLimitExceededException
 * @retryIfException ServiceUnavailableException
 */

基于自定义方法进行重试

对于是否应该重试的更复杂逻辑,定义一个自定义的重试方法

/**
 * @retryAttempts 3
 * @retryIfMethod isRateLimitExceededException
 */
public function testWithCustomRetryMethod()
{
    // retries only if the method `isRateLimitExceededException` returns true.
}

/**
 * @param Exception $e
 */
private function isRateLimitExceededException(Exception $e)
{
    // Check if HTTP Status code is 429 "Too many requests"
    return ($e instanceof HttpException && $e->getStatusCode() == 429);
}

通过将参数传递到注解中来定义重试方法的可任意参数

/**
 * @retryAttempts 3
 * @retryIfMethod exceptionStatusCode 429
 */
public function testWithCustomRetryMethod()
{
    // retries only if the method `exceptionStatusCode` returns true.
}

/**
 * @param Exception $e
 */
private function exceptionStatusCode(Exception $e, $statusCode)
{
    // Check if HTTP status code is $statusCode
    return ($e instanceof HttpException && $e->getStatusCode() == $statusCode);
}

配置延迟

在每个重试之间的持续时间延迟

/**
 * @retryAttempts 3
 * @retryDelaySeconds 10
 */

基于指数增加的重试尝试次数的延迟量

/**
 * @retryAttempts 3
 * @retryDelayMethod exponentialBackoff
 */

exponentialBackoff方法的行为是从1秒开始并增加到最大60秒。最大延迟可以通过向注解提供一个第二个参数来自定义。

/**
 * This test will delay with exponential backoff, with a maximum delay of 10 minutes.
 *
 * @retryAttempts 30
 * @retryDelayMethod exponentialBackoff 600
 */

定义自定义延迟方法

/**
 * @retryAttempts 3
 * @retryDelayMethod myCustomDelay
 */
public function testWithCustomDelay()
{
    // retries using the method `myCustomDelay`.
}

/**
 * @param int $attempt The current test attempt
 */
private function myCustomDelay($attempt)
{
    // Doubles the sleep each attempt, but not longer than 10 seconds.
    sleep(min($attempt * 2, 10));
}

通过将参数传递到注解中来定义延迟函数的可任意参数

/**
 * @retryAttempts 3
 * @retryDelayMethod myCustomDelay 10 60
 */
public function testWithCustomDelay()
{
    // retries using the method `myCustomDelay`.
}

/**
 * @param int $attempt The current test attempt.
 * @param int $multiplier Rate of exponential backoff delay.
 * @param int $maxDelay Maximum time to wait regardless of retry attempt.
 */
private function myCustomDelay($attempt, $multiplier, $maxDelay)
{
    // Increases exponentially
    sleep(min($attempt * $multiplier, $max));
}