keboola / phpunit-retry-annotations
用于在PHPUnit中重试测试方法和类的特性
v0.5
2024-03-08 09:32 UTC
Requires
- php: ^7.4|^8.0
- ext-dom: *
Requires (Dev)
- phpcompatibility/php-compatibility: ^9.3
- phpstan/phpstan: ^1.6
- phpstan/phpstan-phpunit: ^1.1
- phpunit/phpunit: ^9.3
- squizlabs/php_codesniffer: ^3.6
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\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)); }