lirik44 / phpunit-retry-annotations
为PHPUnit中的测试方法和类提供重试功能的特质,针对selenium php-webdriver进行了修改
v1.0.1
2023-12-03 10:05 UTC
Requires
- php: ^7.1|^8.0
- phpunit/phpunit: ^7.1|^8.0|^9.0
Requires (Dev)
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\IncompleteTestError
和PHPUnit\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)); }