lirik44/phpunit-retry-annotations

为PHPUnit中的测试方法和类提供重试功能的特质,针对selenium php-webdriver进行了修改

v1.0.1 2023-12-03 10:05 UTC

This package is auto-updated.

Last update: 2024-10-03 12:03:41 UTC


README

为PHPUnit中的测试方法和类提供重试功能的特质。

安装

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

您应该在项目中自定义SELENIUM_HUB的url。

配置重试

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

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