bshaffer/phpunit-retry-annotations

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

v0.3 2022-07-18 23:39 UTC

This package is auto-updated.

Last update: 2024-09-19 05:23:35 UTC


README

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

安装

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

配置重试

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

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