Retry
The plugin provides the #[Retry]#[Retry(int $maxAttempts = 3, bool $markFlaky = true)]Declares a retry policy for a test on failure. attribute and an interceptor that retry a failed test a specified number of times. If the test passes on retry, it's marked as flaky. The attribute can be placed on a method, function, or an entire class — in the latter case, the policy applies to all tests in the class.
The plugin does not require setup.
#[Retry]
Declares a retry policy for a test on failure.
#[Retry(int $maxAttempts = 3, bool $markFlaky = true)]Works with any test type: regular tests, inline tests, benchmarks. When placed on a class (Test Case), applies to all tests within it.
Parameters:
$maxAttempts- Maximum number of attempts, including the first run. For example,
3means up to two retries after the initial failure. $markFlaky- Whether to mark the test as flaky if it only passed on retry. Defaults to
true.
Examples:
Retry a test up to 3 times:
#[Retry]
public function flakyExternalService(): void
{
$response = HttpClient::get('https://api.example.com/health');
Assert::same(200, $response->statusCode);
}On a class — all tests inside inherit the retry policy:
#[Retry(maxAttempts: 5, markFlaky: false)]
final class ExternalApiTest
{
public function checkHealth(): void { /* ... */ }
public function checkStatus(): void { /* ... */ }
}Suite-Level Policy
The attribute sets a retry policy for a specific test or class. To apply retries to an entire Test Suite, use the RetryPolicyRunInterceptor\Testo\Retry\Interceptor\RetryPolicyRunInterceptor directly — add it to the pipeline via a plugin:
return new ApplicationConfig(
suites: [
new SuiteConfig(
name: 'Integration',
location: ['tests/Integration'],
plugins: [
// ...
new class implements PluginConfigurator {
#[\Override]
public function configure(Container $container): void
{
$container->get(InterceptorProvider::class)->addInterceptor(
$container->make(RetryPolicyRunInterceptor::class, [new Retry(maxAttempts: 3)]),
);
}
},
],
),
],
);This way all tests in the Integration Test Suite will be retried up to 3 times on failure, without placing the attribute on each test individually.
What happens if a retry policy is defined at multiple levels?
When multiple retry policies are defined, only the closest one to the test applies. For example, if the Test Suite has maxAttempts: 3, the class has 2, and the method has 5, the test will retry up to 5 times. Policies do not stack.