protected function runTest() in PHPUnit\Framework\TestCase provided an extension point to change the actual run implementation. That enabled various use-cases around exception handling and specialized test execution.
One additional use-case that has not been mentioned yet is to retry tests that might be unstable.
It would be terrific if PHPUnit could provide an officially blessed extension point to change test execution.
See related issues:
Here is an example of how runTest was used for a retry implementation:
/**
* @mixin TestCase
* @phpstan-require-extends TestCase
*/
trait ResilientTest
{
#[Override]
final protected function runTest(): mixed
{
if (!self::shouldRetryTest($this)) {
return parent::runTest();
}
$maxRetries = self::retryTimes($this);
for ($retry = 0; $retry < $maxRetries; ++$retry) {
try {
return parent::runTest();
} catch (SkippedTest|IncompleteTest $e) {
throw $e;
} catch (Throwable $e) {
if ($retry === $maxRetries - 1) {
throw $e;
}
error_log(sprintf('Retrying %s (%d of %d)', $this->name(), $retry + 1, $maxRetries));
}
}
return parent::runTest();
}
private static function shouldRetryTest(TestCase $testCase): bool
{
return self::retryTimes($testCase) > 1;
}
private static function retryTimes(TestCase $testCase): int
{
$class = new ReflectionObject($testCase);
$currentClass = $class;
do {
$classAttributes = $currentClass->getAttributes(Retry::class);
if (count($classAttributes) > 0) {
return $classAttributes[0]->newInstance()->times ?? 1;
}
$methodAttributes = $currentClass->getMethod($testCase->name())
->getAttributes(Retry::class);
if (count($methodAttributes) > 0) {
return $methodAttributes[0]->newInstance()->times ?? 1;
}
} while (($currentClass = $currentClass->getParentClass()) !== false);
return 1;
}
}
protected function runTest()inPHPUnit\Framework\TestCaseprovided an extension point to change the actual run implementation. That enabled various use-cases around exception handling and specialized test execution.One additional use-case that has not been mentioned yet is to retry tests that might be unstable.
It would be terrific if PHPUnit could provide an officially blessed extension point to change test execution.
See related issues:
runTestfunction #6172Here is an example of how
runTestwas used for a retry implementation: