diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 7dace6b1df8..02c2f6282da 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -24,6 +24,9 @@ ->notName('TestAttributeOnHookMethodsTest.php') // InvokableConstraintAndPipeOperatorTest.php uses PHP 8.5 syntax ->notName('InvokableConstraintAndPipeOperatorTest.php') + // NoReturnTypeTest.php and RepeatAttributeWithoutReturnTypeTest.php must have a method without a return type declaration + ->notPath('repeat/_files/NoReturnTypeTest.php') + ->notPath('repeat/_files/RepeatAttributeWithoutReturnTypeTest.php') // FirstPartyClass.php and PhpDeprecationTest.php must not use declare(strict_types=1); ->notPath('error-handler/_files/php-deprecation/src/FirstPartyClass.php') ->notPath('error-handler/_files/php-deprecation/tests/PhpDeprecationTest.php') diff --git a/phpunit.xml b/phpunit.xml index aa383a74a29..c13a944af95 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -37,6 +37,7 @@ tests/end-to-end/migration tests/end-to-end/phpt tests/end-to-end/regression + tests/end-to-end/repeat tests/end-to-end/test-doubles/generator tests/end-to-end/test-doubles/runtime tests/end-to-end/testdox @@ -46,6 +47,7 @@ tests/end-to-end/groups-from-configuration/_files tests/end-to-end/logging/_files tests/end-to-end/migration/_files + tests/end-to-end/repeat/_files tests/end-to-end/self-direct-indirect/_files tests/end-to-end/testdox/_files diff --git a/src/Event/Events/TestSuite/Finished.php b/src/Event/Events/TestSuite/Finished.php index 378768de01c..305809548a2 100644 --- a/src/Event/Events/TestSuite/Finished.php +++ b/src/Event/Events/TestSuite/Finished.php @@ -47,11 +47,31 @@ public function testSuite(): TestSuite */ public function asString(): string { + $prefix = 'Test Suite Finished'; + $unit = 'test'; + + if ($this->testSuite->isForTestMethodWithDataProvider()) { + $prefix = 'Test Suite for Test Method with Data Provider Finished'; + $unit = 'data set'; + } elseif ($this->testSuite->isForRepeatedTestMethod()) { + $prefix = 'Test Suite for Repeated Test Method Finished'; + $unit = 'repetition'; + } + + $count = $this->testSuite->count(); + $plural = ''; + + if ($count !== 1) { + $plural = 's'; + } + return sprintf( - 'Test Suite Finished (%s, %d test%s)', + '%s (%s, %d %s%s)', + $prefix, $this->testSuite->name(), - $this->testSuite->count(), - $this->testSuite->count() !== 1 ? 's' : '', + $count, + $unit, + $plural, ); } } diff --git a/src/Event/Events/TestSuite/Started.php b/src/Event/Events/TestSuite/Started.php index c558d7679b0..54e7b1ff676 100644 --- a/src/Event/Events/TestSuite/Started.php +++ b/src/Event/Events/TestSuite/Started.php @@ -47,11 +47,31 @@ public function testSuite(): TestSuite */ public function asString(): string { + $prefix = 'Test Suite Started'; + $unit = 'test'; + + if ($this->testSuite->isForTestMethodWithDataProvider()) { + $prefix = 'Test Suite for Test Method with Data Provider Started'; + $unit = 'data set'; + } elseif ($this->testSuite->isForRepeatedTestMethod()) { + $prefix = 'Test Suite for Repeated Test Method Started'; + $unit = 'repetition'; + } + + $count = $this->testSuite->count(); + $plural = ''; + + if ($count !== 1) { + $plural = 's'; + } + return sprintf( - 'Test Suite Started (%s, %d test%s)', + '%s (%s, %d %s%s)', + $prefix, $this->testSuite->name(), - $this->testSuite->count(), - $this->testSuite->count() !== 1 ? 's' : '', + $count, + $unit, + $plural, ); } } diff --git a/src/Event/Value/Test/TestMethod.php b/src/Event/Value/Test/TestMethod.php index 3cc2590833a..ed142125bf3 100644 --- a/src/Event/Value/Test/TestMethod.php +++ b/src/Event/Value/Test/TestMethod.php @@ -39,24 +39,38 @@ private MetadataCollection $metadata; private TestDataCollection $testData; + /** + * @var positive-int + */ + private int $repetition; + + /** + * @var positive-int + */ + private int $totalRepetitions; + /** * @param class-string $className * @param non-empty-string $methodName * @param non-empty-string $file * @param non-negative-int $line + * @param positive-int $repetition + * @param positive-int $totalRepetitions * * @internal This method is not covered by the backward compatibility promise for PHPUnit */ - public function __construct(string $className, string $methodName, string $file, int $line, TestDox $testDox, MetadataCollection $metadata, TestDataCollection $testData) + public function __construct(string $className, string $methodName, string $file, int $line, TestDox $testDox, MetadataCollection $metadata, TestDataCollection $testData, int $repetition = 1, int $totalRepetitions = 1) { parent::__construct($file); - $this->className = $className; - $this->methodName = $methodName; - $this->line = $line; - $this->testDox = $testDox; - $this->metadata = $metadata; - $this->testData = $testData; + $this->className = $className; + $this->methodName = $methodName; + $this->line = $line; + $this->testDox = $testDox; + $this->metadata = $metadata; + $this->testData = $testData; + $this->repetition = $repetition; + $this->totalRepetitions = $totalRepetitions; } /** @@ -98,6 +112,27 @@ public function testData(): TestDataCollection return $this->testData; } + /** + * @return positive-int + */ + public function repetition(): int + { + return $this->repetition; + } + + /** + * @return positive-int + */ + public function totalRepetitions(): int + { + return $this->totalRepetitions; + } + + public function isRepeated(): bool + { + return $this->totalRepetitions > 1; + } + public function isTestMethod(): true { return true; @@ -114,6 +149,14 @@ public function id(): string $buffer .= '#' . $this->testData->dataFromDataProvider()->dataSetName(); } + if ($this->totalRepetitions > 1) { + $buffer .= sprintf( + ' (repetition %d of %d)', + $this->repetition, + $this->totalRepetitions, + ); + } + return $buffer; } @@ -130,24 +173,32 @@ public function nameWithClass(): string */ public function name(): string { - if (!$this->testData->hasDataFromDataProvider()) { - return $this->methodName; + $name = $this->methodName; + + if ($this->testData->hasDataFromDataProvider()) { + $dataSetName = $this->testData->dataFromDataProvider()->dataSetName(); + + if (is_int($dataSetName)) { + $name .= sprintf( + ' with data set #%d', + $dataSetName, + ); + } else { + $name .= sprintf( + ' with data set "%s"', + $dataSetName, + ); + } } - $dataSetName = $this->testData->dataFromDataProvider()->dataSetName(); - - if (is_int($dataSetName)) { - $dataSetName = sprintf( - ' with data set #%d', - $dataSetName, - ); - } else { - $dataSetName = sprintf( - ' with data set "%s"', - $dataSetName, + if ($this->totalRepetitions > 1) { + $name .= sprintf( + ' (repetition %d of %d)', + $this->repetition, + $this->totalRepetitions, ); } - return $this->methodName . $dataSetName; + return $name; } } diff --git a/src/Event/Value/Test/TestMethodBuilder.php b/src/Event/Value/Test/TestMethodBuilder.php index dc1a32ef8ab..6e69e869a7d 100644 --- a/src/Event/Value/Test/TestMethodBuilder.php +++ b/src/Event/Value/Test/TestMethodBuilder.php @@ -45,6 +45,8 @@ public static function fromTestCase(TestCase $testCase, bool $useTestCaseForTest $testDox, MetadataRegistry::parser()->forClassAndMethod($testCase::class, $methodName), self::dataFor($testCase), + $testCase->repetition(), + $testCase->totalRepetitions(), ); } diff --git a/src/Event/Value/TestSuite/TestSuite.php b/src/Event/Value/TestSuite/TestSuite.php index 73672ae00ff..35b38c6a786 100644 --- a/src/Event/Value/TestSuite/TestSuite.php +++ b/src/Event/Value/TestSuite/TestSuite.php @@ -78,4 +78,12 @@ public function isForTestMethodWithDataProvider(): bool { return false; } + + /** + * @phpstan-assert-if-true TestSuiteForRepeatedTestMethod $this + */ + public function isForRepeatedTestMethod(): bool + { + return false; + } } diff --git a/src/Event/Value/TestSuite/TestSuiteBuilder.php b/src/Event/Value/TestSuite/TestSuiteBuilder.php index 3192636baa9..b064e308928 100644 --- a/src/Event/Value/TestSuite/TestSuiteBuilder.php +++ b/src/Event/Value/TestSuite/TestSuiteBuilder.php @@ -14,10 +14,13 @@ use function count; use function explode; use function method_exists; +use function strpos; +use function substr; use PHPUnit\Event\Code\Test; use PHPUnit\Event\Code\TestCollection; use PHPUnit\Event\RuntimeException; use PHPUnit\Framework\DataProviderTestSuite; +use PHPUnit\Framework\RepeatTestSuite; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestSuite as FrameworkTestSuite; use PHPUnit\Runner\Phpt\TestCase as PhptTestCase; @@ -66,6 +69,44 @@ public static function from(FrameworkTestSuite $testSuite): TestSuite ); } + if ($testSuite instanceof RepeatTestSuite) { + $name = $testSuite->name(); + + $separatorPosition = strpos($name, '::'); + + assert($separatorPosition !== false); + + $className = substr($name, 0, $separatorPosition); + $methodName = substr($name, $separatorPosition + 2); + + $hashPosition = strpos($methodName, '#'); + + if ($hashPosition !== false) { + $methodName = substr($methodName, 0, $hashPosition); + } + + assert($className !== '' && class_exists($className)); + assert($methodName !== '' && method_exists($className, $methodName)); + + $reflector = new ReflectionMethod($className, $methodName); + + $file = $reflector->getFileName(); + $line = $reflector->getStartLine(); + + assert($file !== false); + assert($line !== false); + + return new TestSuiteForRepeatedTestMethod( + $name, + $testSuite->count(), + TestCollection::fromArray($tests), + $className, + $methodName, + $file, + $line, + ); + } + if ($testSuite->isForTestClass()) { $testClassName = $testSuite->name(); diff --git a/src/Event/Value/TestSuite/TestSuiteForRepeatedTestMethod.php b/src/Event/Value/TestSuite/TestSuiteForRepeatedTestMethod.php new file mode 100644 index 00000000000..e9679aeac16 --- /dev/null +++ b/src/Event/Value/TestSuite/TestSuiteForRepeatedTestMethod.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestSuite; + +use PHPUnit\Event\Code\TestCollection; + +/** + * @immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final readonly class TestSuiteForRepeatedTestMethod extends TestSuite +{ + /** + * @var class-string + */ + private string $className; + + /** + * @var non-empty-string + */ + private string $methodName; + private string $file; + private int $line; + + /** + * @param non-empty-string $name + * @param class-string $className + * @param non-empty-string $methodName + */ + public function __construct(string $name, int $size, TestCollection $tests, string $className, string $methodName, string $file, int $line) + { + parent::__construct($name, $size, $tests); + + $this->className = $className; + $this->methodName = $methodName; + $this->file = $file; + $this->line = $line; + } + + /** + * @return class-string + */ + public function className(): string + { + return $this->className; + } + + /** + * @return non-empty-string + */ + public function methodName(): string + { + return $this->methodName; + } + + public function file(): string + { + return $this->file; + } + + public function line(): int + { + return $this->line; + } + + public function isForRepeatedTestMethod(): true + { + return true; + } +} diff --git a/src/Framework/Attributes/Repeat.php b/src/Framework/Attributes/Repeat.php new file mode 100644 index 00000000000..4932df7af9e --- /dev/null +++ b/src/Framework/Attributes/Repeat.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; + +/** + * @immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_METHOD)] +final readonly class Repeat +{ + /** + * @var positive-int + */ + private int $times; + + /** + * @var positive-int + */ + private int $failureThreshold; + + /** + * @param positive-int $times + * @param positive-int $failureThreshold + */ + public function __construct(int $times, int $failureThreshold = 1) + { + $this->times = $times; + $this->failureThreshold = $failureThreshold; + } + + /** + * @return positive-int + */ + public function times(): int + { + return $this->times; + } + + /** + * @return positive-int + */ + public function failureThreshold(): int + { + return $this->failureThreshold; + } +} diff --git a/src/Framework/RepeatTestSuite.php b/src/Framework/RepeatTestSuite.php new file mode 100644 index 00000000000..251c2af7214 --- /dev/null +++ b/src/Framework/RepeatTestSuite.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use function assert; +use PHPUnit\Event; +use PHPUnit\Event\NoPreviousThrowableException; +use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade; +use SebastianBergmann\CodeCoverage\InvalidArgumentException; +use SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException; + +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RepeatTestSuite extends TestSuite +{ + /** + * @var positive-int + */ + private int $failureThreshold = 1; + + /** + * @param non-empty-string $name + * @param non-empty-list $tests + * @param positive-int $failureThreshold + */ + public static function fromTests(string $name, array $tests, int $failureThreshold): self + { + $suite = self::empty($name); + + $suite->failureThreshold = $failureThreshold; + + foreach ($tests as $test) { + $suite->addTest($test); + } + + return $suite; + } + + /** + * @throws Event\RuntimeException + * @throws Exception + * @throws InvalidArgumentException + * @throws NoPreviousThrowableException + * @throws UnintentionallyCoveredCodeException + */ + public function run(): void + { + if ($this->isEmpty()) { + return; + } + + $emitter = Event\Facade::emitter(); + $testSuiteValueObjectForEvents = Event\TestSuite\TestSuiteBuilder::from($this); + + $emitter->testSuiteStarted($testSuiteValueObjectForEvents); + + $failureCount = 0; + $lastFailedRepetition = 0; + + foreach ($this as $test) { + assert($test instanceof TestCase); + + if (TestResultFacade::shouldStop()) { + $emitter->testRunnerExecutionAborted(); + + break; + } + + if ($failureCount >= $this->failureThreshold) { + $test->markSkippedForRepeatAbort($lastFailedRepetition); + + continue; + } + + $test->run(); + + if ($test->status()->isFailure() || $test->status()->isError()) { + $failureCount++; + $lastFailedRepetition = $test->repetition(); + } + } + + $emitter->testSuiteFinished($testSuiteValueObjectForEvents); + } + + /** + * @param list $dependencies + */ + public function setDependencies(array $dependencies): void + { + foreach ($this->tests() as $test) { + assert($test instanceof TestCase); + + $test->setDependencies($dependencies); + } + } + + /** + * @return list + */ + public function provides(): array + { + $tests = $this->tests(); + + if ($tests === []) { + return []; + } + + assert($tests[0] instanceof TestCase); + + return $tests[0]->provides(); + } + + /** + * @return list + */ + public function requires(): array + { + $tests = $this->tests(); + + if ($tests === []) { + return []; + } + + assert($tests[0] instanceof TestCase); + + return $tests[0]->requires(); + } + + public function sortId(): string + { + $tests = $this->tests(); + + assert($tests !== []); + assert($tests[0] instanceof TestCase); + + return $tests[0]->sortId(); + } +} diff --git a/src/Framework/TestBuilder.php b/src/Framework/TestBuilder.php index e51427e13b8..b3e636a8ab6 100644 --- a/src/Framework/TestBuilder.php +++ b/src/Framework/TestBuilder.php @@ -13,6 +13,9 @@ use function assert; use function get_parent_class; use function preg_match; +use function range; +use function sprintf; +use PHPUnit\Event\Facade as EventFacade; use PHPUnit\Metadata\Api\DataProvider; use PHPUnit\Metadata\Api\Groups; use PHPUnit\Metadata\Api\ProvidedData; @@ -23,10 +26,13 @@ use PHPUnit\Metadata\ExcludeStaticPropertyFromBackup; use PHPUnit\Metadata\Parser\Registry as MetadataRegistry; use PHPUnit\Metadata\PreserveGlobalState; +use PHPUnit\Metadata\Repeat as RepeatMetadata; use PHPUnit\Runner\ErrorHandler; use PHPUnit\Runner\Filter\MethodNameFilterCompiler; use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry; use ReflectionClass; +use ReflectionMethod; +use ReflectionNamedType; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit @@ -41,12 +47,52 @@ * @param ReflectionClass $theClass * @param non-empty-string $methodName * @param list $groups + * @param positive-int $numberOfRuns + * @param positive-int $failureThreshold * * @throws InvalidDataProviderException */ - public function build(ReflectionClass $theClass, string $methodName, array $groups = []): Test + public function build(ReflectionClass $theClass, string $methodName, array $groups = [], int $numberOfRuns = 1, int $failureThreshold = 1): Test { - $className = $theClass->getName(); + $className = $theClass->getName(); + $runTestInSeparateProcess = $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName); + $preserveGlobalState = $this->shouldGlobalStateBePreserved($className, $methodName); + $backupSettings = $this->backupSettings($className, $methodName); + + $repeatMetadata = MetadataRegistry::parser()->forMethod($className, $methodName)->isRepeat(); + + if ($repeatMetadata->isNotEmpty()) { + $metadata = $repeatMetadata->asArray()[0]; + + assert($metadata instanceof RepeatMetadata); + + $numberOfRuns = $metadata->times(); + $failureThreshold = $metadata->failureThreshold(); + + if (!$this->hasVoidReturnType($theClass->getMethod($methodName))) { + EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( + sprintf( + 'Method %s::%s is annotated with #[Repeat] but does not have a void return type declaration and will not be repeated', + $className, + $methodName, + ), + ); + } + + if (!$this->doesNotDependOnAnotherTest($className, $methodName)) { + EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( + sprintf( + 'Method %s::%s is annotated with #[Repeat] but depends on another test and will not be repeated', + $className, + $methodName, + ), + ); + } + } + + $repeat = $numberOfRuns > 1 && + $this->hasVoidReturnType($theClass->getMethod($methodName)) && + $this->doesNotDependOnAnotherTest($className, $methodName); $data = null; @@ -66,10 +112,24 @@ public function build(ReflectionClass $theClass, string $methodName, array $grou $methodName, $className, $data, - $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), - $this->shouldGlobalStateBePreserved($className, $methodName), - $this->backupSettings($className, $methodName), + $runTestInSeparateProcess, + $preserveGlobalState, + $backupSettings, $groups, + $repeat ? $numberOfRuns : 1, + $failureThreshold, + ); + } + + if ($repeat) { + return $this->buildRepeatTestSuite( + $className, + $methodName, + $numberOfRuns, + $failureThreshold, + $runTestInSeparateProcess, + $preserveGlobalState, + $backupSettings, ); } @@ -83,9 +143,9 @@ public function build(ReflectionClass $theClass, string $methodName, array $grou $this->configureTestCase( $test, - $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), - $this->shouldGlobalStateBePreserved($className, $methodName), - $this->backupSettings($className, $methodName), + $runTestInSeparateProcess, + $preserveGlobalState, + $backupSettings, ); return $test; @@ -97,8 +157,10 @@ public function build(ReflectionClass $theClass, string $methodName, array $grou * @param array $data * @param BackupSettings $backupSettings * @param list $groups + * @param positive-int $numberOfRuns + * @param positive-int $failureThreshold */ - private function buildDataProviderTestSuite(string $methodName, string $className, array $data, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, array $backupSettings, array $groups): DataProviderTestSuite + private function buildDataProviderTestSuite(string $methodName, string $className, array $data, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, array $backupSettings, array $groups, int $numberOfRuns = 1, int $failureThreshold = 1): DataProviderTestSuite { $dataProviderTestSuite = DataProviderTestSuite::empty( $className . '::' . $methodName, @@ -110,21 +172,83 @@ private function buildDataProviderTestSuite(string $methodName, string $classNam ); foreach ($data as $_dataName => $_data) { - $_test = new $className($methodName); + if ($numberOfRuns > 1) { + $tests = []; + + foreach (range(1, $numberOfRuns) as $i) { + $_test = new $className($methodName); + + $_test->setData($_dataName, $_data->value()); + $_test->setRepetition($i, $numberOfRuns); + + $this->configureTestCase( + $_test, + $runTestInSeparateProcess, + $preserveGlobalState, + $backupSettings, + ); + + $tests[] = $_test; + } + + $dataProviderTestSuite->addTest( + RepeatTestSuite::fromTests( + $className . '::' . $methodName . '#' . $_dataName, + $tests, + $failureThreshold, + ), + $groups, + ); + } else { + $_test = new $className($methodName); + + $_test->setData($_dataName, $_data->value()); + + $this->configureTestCase( + $_test, + $runTestInSeparateProcess, + $preserveGlobalState, + $backupSettings, + ); + + $dataProviderTestSuite->addTest($_test, $groups); + } + } + + return $dataProviderTestSuite; + } - $_test->setData($_dataName, $_data->value()); + /** + * @param class-string $className + * @param non-empty-string $methodName + * @param positive-int $numberOfRuns + * @param positive-int $failureThreshold + * @param array{backupGlobals: ?true, backupGlobalsExcludeList: list, backupStaticProperties: ?true, backupStaticPropertiesExcludeList: array>} $backupSettings + */ + private function buildRepeatTestSuite(string $className, string $methodName, int $numberOfRuns, int $failureThreshold, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, array $backupSettings): RepeatTestSuite + { + $tests = []; + + foreach (range(1, $numberOfRuns) as $i) { + $test = new $className($methodName); + + $test->setRepetition($i, $numberOfRuns); $this->configureTestCase( - $_test, + $test, $runTestInSeparateProcess, $preserveGlobalState, $backupSettings, ); - $dataProviderTestSuite->addTest($_test, $groups); + $tests[] = $test; } - return $dataProviderTestSuite; + return RepeatTestSuite::fromTests( + $className . '::' . $methodName, + $tests, + $failureThreshold, + ); } /** @@ -323,4 +447,30 @@ private function filterExcludesMethod(string $className, string $methodName): bo return $result === 0; } + + private function hasVoidReturnType(ReflectionMethod $method): bool + { + if (!$method->hasReturnType()) { + return false; + } + + $returnType = $method->getReturnType(); + + if (!$returnType instanceof ReflectionNamedType) { + return false; + } + + return $returnType->getName() === 'void'; + } + + /** + * @param class-string $className + * @param non-empty-string $methodName + */ + private function doesNotDependOnAnotherTest(string $className, string $methodName): bool + { + $metadata = MetadataRegistry::parser()->forClassAndMethod($className, $methodName); + + return $metadata->isDepends()->isEmpty(); + } } diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php index 71108967cfd..8aba5681cca 100644 --- a/src/Framework/TestCase.php +++ b/src/Framework/TestCase.php @@ -233,6 +233,16 @@ abstract class TestCase extends Assert implements Reorderable, SelfDescribing, T private false|string $previousErrorLogTarget = false; private ?string $emptyDataProviderSkipMessage = null; + /** + * @var positive-int + */ + private int $repetition = 1; + + /** + * @var positive-int + */ + private int $totalRepetitions = 1; + /** * @param non-empty-string $name * @@ -1003,6 +1013,56 @@ final public function wasPrepared(): bool return $this->wasPrepared; } + /** + * @return positive-int + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + final public function repetition(): int + { + return $this->repetition; + } + + /** + * @return positive-int + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + final public function totalRepetitions(): int + { + return $this->totalRepetitions; + } + + /** + * @param positive-int $repetition + * @param positive-int $totalRepetitions + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + final public function setRepetition(int $repetition, int $totalRepetitions): void + { + $this->repetition = $repetition; + $this->totalRepetitions = $totalRepetitions; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + final public function markSkippedForRepeatAbort(int $failedRepetition): void + { + $message = sprintf( + 'Remaining repetition skipped after failure in repetition %d', + $failedRepetition, + ); + + Event\Facade::emitter()->testSkipped( + $this->valueObjectForEvents(), + $message, + ); + + $this->status = TestStatus::skipped($message); + } + /** * Returns a matcher that matches when the method is executed * zero or more times. diff --git a/src/Framework/TestSuite.php b/src/Framework/TestSuite.php index 6490b22301c..d749deb4837 100644 --- a/src/Framework/TestSuite.php +++ b/src/Framework/TestSuite.php @@ -97,8 +97,9 @@ public static function empty(string $name): static /** * @param ReflectionClass $class * @param list $groups + * @param positive-int $numberOfRuns */ - public static function fromClassReflector(ReflectionClass $class, array $groups = []): static + public static function fromClassReflector(ReflectionClass $class, array $groups = [], int $numberOfRuns = 1): static { $testSuite = new static($class->getName()); @@ -119,7 +120,7 @@ public static function fromClassReflector(ReflectionClass $class, array $groups continue; } - $testSuite->addTestMethod($class, $method, $groups); + $testSuite->addTestMethod($class, $method, $groups, $numberOfRuns); } if ($testSuite->isEmpty()) { @@ -189,10 +190,11 @@ public function addTest(Test $test, array $groups = []): void * * @param ReflectionClass $testClass * @param list $groups + * @param positive-int $numberOfRuns * * @throws Exception */ - public function addTestSuite(ReflectionClass $testClass, array $groups = []): void + public function addTestSuite(ReflectionClass $testClass, array $groups = [], int $numberOfRuns = 1): void { $className = $testClass->getName(); @@ -215,7 +217,7 @@ public function addTestSuite(ReflectionClass $testClass, array $groups = []): vo ); } - $this->addTest(self::fromClassReflector($testClass, $groups), $groups); + $this->addTest(self::fromClassReflector($testClass, $groups, $numberOfRuns), $groups); } /** @@ -227,10 +229,11 @@ public function addTestSuite(ReflectionClass $testClass, array $groups = []): vo * leaving the current test run untouched. * * @param list $groups + * @param positive-int $numberOfRuns * * @throws Exception */ - public function addTestFile(string $filename, array $groups = []): void + public function addTestFile(string $filename, array $groups = [], int $numberOfRuns = 1): void { try { if (str_ends_with($filename, '.phpt') && is_file($filename)) { @@ -239,6 +242,7 @@ public function addTestFile(string $filename, array $groups = []): void $this->addTestSuite( (new TestSuiteLoader)->load($filename), $groups, + $numberOfRuns, ); } } catch (RunnerException $e) { @@ -256,13 +260,14 @@ public function addTestFile(string $filename, array $groups = []): void * Wrapper for addTestFile() that adds multiple test files. * * @param iterable $fileNames + * @param positive-int $numberOfRuns * * @throws Exception */ - public function addTestFiles(iterable $fileNames): void + public function addTestFiles(iterable $fileNames, int $numberOfRuns = 1): void { foreach ($fileNames as $filename) { - $this->addTestFile((string) $filename); + $this->addTestFile((string) $filename, [], $numberOfRuns); } } @@ -511,16 +516,17 @@ public function isForTestClass(): bool /** * @param ReflectionClass $class * @param list $groups + * @param positive-int $numberOfRuns * * @throws Exception */ - protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method, array $groups): void + protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method, array $groups, int $numberOfRuns = 1): void { $className = $class->getName(); $methodName = $method->getName(); try { - $test = (new TestBuilder)->build($class, $methodName, $groups); + $test = (new TestBuilder)->build($class, $methodName, $groups, $numberOfRuns); } catch (InvalidDataProviderException $e) { if ($e->getProviderLabel() === null) { $message = sprintf( @@ -564,7 +570,7 @@ protected function addTestMethod(ReflectionClass $class, ReflectionMethod $metho return; } - if ($test instanceof TestCase || $test instanceof DataProviderTestSuite) { + if ($test instanceof TestCase || $test instanceof DataProviderTestSuite || $test instanceof RepeatTestSuite) { $test->setDependencies( Dependencies::dependencies($class->getName(), $methodName), ); diff --git a/src/Logging/JUnit/JunitXmlLogger.php b/src/Logging/JUnit/JunitXmlLogger.php index f0bdeb5366d..93b9e7b247f 100644 --- a/src/Logging/JUnit/JunitXmlLogger.php +++ b/src/Logging/JUnit/JunitXmlLogger.php @@ -12,7 +12,6 @@ use const PHP_EOL; use function assert; use function basename; -use function is_int; use function sprintf; use function str_replace; use function trim; @@ -448,25 +447,7 @@ private function name(Test $test): string assert($test instanceof TestMethod); - if (!$test->testData()->hasDataFromDataProvider()) { - return $test->methodName(); - } - - $dataSetName = $test->testData()->dataFromDataProvider()->dataSetName(); - - if (is_int($dataSetName)) { - return sprintf( - '%s with data set #%d', - $test->methodName(), - $dataSetName, - ); - } - - return sprintf( - '%s with data set "%s"', - $test->methodName(), - $dataSetName, - ); + return $test->name(); } /** diff --git a/src/Metadata/Metadata.php b/src/Metadata/Metadata.php index 3a3f2de34b3..09f47141b32 100644 --- a/src/Metadata/Metadata.php +++ b/src/Metadata/Metadata.php @@ -482,6 +482,15 @@ public static function runTestsInSeparateProcesses(): RunTestsInSeparateProcesse return new RunTestsInSeparateProcesses(Level::CLASS_LEVEL); } + /** + * @param positive-int $times + * @param positive-int $failureThreshold + */ + public static function repeat(int $times, int $failureThreshold): Repeat + { + return new Repeat(Level::METHOD_LEVEL, $times, $failureThreshold); + } + public static function runInSeparateProcess(): RunInSeparateProcess { return new RunInSeparateProcess(Level::METHOD_LEVEL); @@ -820,6 +829,14 @@ public function isIgnorePhpunitDeprecations(): bool return false; } + /** + * @phpstan-assert-if-true Repeat $this + */ + public function isRepeat(): bool + { + return false; + } + /** * @phpstan-assert-if-true RunInSeparateProcess $this */ diff --git a/src/Metadata/MetadataCollection.php b/src/Metadata/MetadataCollection.php index 975d5af6b74..2f6e43f459e 100644 --- a/src/Metadata/MetadataCollection.php +++ b/src/Metadata/MetadataCollection.php @@ -391,6 +391,16 @@ public function isIgnorePhpunitWarnings(): self ); } + public function isRepeat(): self + { + return new self( + ...array_filter( + $this->metadata, + static fn (Metadata $metadata): bool => $metadata->isRepeat(), + ), + ); + } + public function isRunInSeparateProcess(): self { return new self( diff --git a/src/Metadata/Parser/AttributeParser.php b/src/Metadata/Parser/AttributeParser.php index a475c35636b..ef5ce175cd6 100644 --- a/src/Metadata/Parser/AttributeParser.php +++ b/src/Metadata/Parser/AttributeParser.php @@ -61,6 +61,7 @@ use PHPUnit\Framework\Attributes\PostCondition; use PHPUnit\Framework\Attributes\PreCondition; use PHPUnit\Framework\Attributes\PreserveGlobalState; +use PHPUnit\Framework\Attributes\Repeat; use PHPUnit\Framework\Attributes\RequiresEnvironmentVariable; use PHPUnit\Framework\Attributes\RequiresFunction; use PHPUnit\Framework\Attributes\RequiresMethod; @@ -894,6 +895,16 @@ public function forMethod(string $className, string $methodName): MetadataCollec break; + case Repeat::class: + assert($attributeInstance instanceof Repeat); + + $result[] = Metadata::repeat( + $attributeInstance->times(), + $attributeInstance->failureThreshold(), + ); + + break; + case RunInSeparateProcess::class: $result[] = Metadata::runInSeparateProcess(); diff --git a/src/Metadata/Repeat.php b/src/Metadata/Repeat.php new file mode 100644 index 00000000000..b84ccc1c8b7 --- /dev/null +++ b/src/Metadata/Repeat.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Metadata; + +/** + * @immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final readonly class Repeat extends Metadata +{ + /** + * @var positive-int + */ + private int $times; + + /** + * @var positive-int + */ + private int $failureThreshold; + + /** + * @param positive-int $times + * @param positive-int $failureThreshold + */ + protected function __construct(Level $level, int $times, int $failureThreshold) + { + parent::__construct($level); + + $this->times = $times; + $this->failureThreshold = $failureThreshold; + } + + public function isRepeat(): true + { + return true; + } + + /** + * @return positive-int + */ + public function times(): int + { + return $this->times; + } + + /** + * @return positive-int + */ + public function failureThreshold(): int + { + return $this->failureThreshold; + } +} diff --git a/src/Runner/TestResult/Collector.php b/src/Runner/TestResult/Collector.php index 3c1fef008bb..19e8093ff82 100644 --- a/src/Runner/TestResult/Collector.php +++ b/src/Runner/TestResult/Collector.php @@ -51,6 +51,7 @@ use PHPUnit\Event\TestSuite\Finished as TestSuiteFinished; use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped; use PHPUnit\Event\TestSuite\Started as TestSuiteStarted; +use PHPUnit\Event\TestSuite\TestSuiteForRepeatedTestMethod; use PHPUnit\Event\TestSuite\TestSuiteForTestClass; use PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider; use PHPUnit\TestRunner\IssueFilter; @@ -350,6 +351,29 @@ public function testSuiteFinished(TestSuiteFinished $event): void return; } + if ($testSuite->isForRepeatedTestMethod()) { + assert($testSuite instanceof TestSuiteForRepeatedTestMethod); + assert(count($testSuite->tests()->asArray()) > 0); + + $test = $testSuite->tests()->asArray()[0]; + + assert($test instanceof TestMethod); + + foreach ($this->testFailedEvents as $testFailedEvent) { + if ($testFailedEvent instanceof AfterLastTestMethodFailed || $testFailedEvent instanceof BeforeFirstTestMethodFailed) { + continue; + } + + if ($testFailedEvent->test()->isTestMethod() && $testFailedEvent->test()->methodName() === $test->methodName()) { + return; + } + } + + PassedTests::instance()->testMethodPassed($test, null); + + return; + } + assert($testSuite instanceof TestSuiteForTestClass); PassedTests::instance()->testClassPassed($testSuite->className()); diff --git a/src/TextUI/Configuration/Cli/Builder.php b/src/TextUI/Configuration/Cli/Builder.php index 782cbd6129f..e7461717dc1 100644 --- a/src/TextUI/Configuration/Cli/Builder.php +++ b/src/TextUI/Configuration/Cli/Builder.php @@ -116,6 +116,7 @@ final class Builder 'do-not-report-useless-tests', 'random-order', 'random-order-seed=', + 'repeat=', 'reverse-order', 'reverse-list', 'static-backup', @@ -363,6 +364,7 @@ public function fromParameters(array $parameters): Configuration $noLogging = null; $processIsolation = null; $randomOrderSeed = null; + $repeat = null; $reportUselessTests = null; $resolveDependencies = null; $reverseList = null; @@ -1209,6 +1211,25 @@ public function fromParameters(array $parameters): Configuration break; + case '--repeat': + if (!is_numeric($option[1]) || + (string) (int) $option[1] !== $option[1] || + (int) $option[1] < 1) { + EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( + sprintf( + 'Option "--repeat %s" ignored because "%s" is not a positive integer', + $option[1], + $option[1], + ), + ); + + break; + } + + $repeat = (int) $option[1]; + + break; + case '--resolve-dependencies': $resolveDependencies = true; @@ -1409,6 +1430,7 @@ public function fromParameters(array $parameters): Configuration $noLogging, $processIsolation, $randomOrderSeed, + $repeat, $reportUselessTests, $resolveDependencies, $reverseList, diff --git a/src/TextUI/Configuration/Cli/Configuration.php b/src/TextUI/Configuration/Cli/Configuration.php index 545682e2ace..da4dec277c1 100644 --- a/src/TextUI/Configuration/Cli/Configuration.php +++ b/src/TextUI/Configuration/Cli/Configuration.php @@ -157,6 +157,11 @@ private ?bool $noLogging; private ?bool $processIsolation; private ?int $randomOrderSeed; + + /** + * @var ?positive-int + */ + private ?int $repeat; private ?bool $reportUselessTests; private ?bool $resolveDependencies; private ?bool $reverseList; @@ -207,11 +212,12 @@ * @param ?non-empty-list $testsUsing * @param ?non-empty-list $testsRequiringPhpExtension * @param ?non-empty-array $iniSettings + * @param ?positive-int $repeat * @param ?non-empty-list $testSuffixes * @param ?non-empty-list $coverageFilter * @param ?non-empty-list $extensions */ - public function __construct(array $arguments, ?string $testFilesFile, ?string $testIdFile, ?string $testIdFilter, ?bool $all, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, bool $checkPhpConfiguration, bool $checkVersion, ?string $colors, null|int|string $columns, ?string $configurationFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4J, ?string $coverageHtml, ?string $coverageOpenClover, ?string $coveragePhp, ?string $coverageText, ?bool $coverageTextShowUncoveredFiles, ?bool $coverageTextShowOnlySummary, ?string $coverageXml, ?bool $coverageXmlIncludeSource, ?bool $pathCoverage, ?bool $branchCoverage, bool $warmCoverageCache, ?int $defaultTimeLimit, ?int $diffContext, ?bool $disableCodeCoverageIgnore, ?bool $disableCoverageTargeting, ?bool $disallowTestOutput, ?bool $enforceTimeLimit, ?array $excludeGroups, ?int $executionOrder, ?int $executionOrderDefects, ?bool $failOnAllIssues, ?bool $failOnDeprecation, ?bool $failOnPhpunitDeprecation, ?bool $failOnPhpunitNotice, ?bool $failOnPhpunitWarning, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnNotice, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?bool $doNotFailOnDeprecation, ?bool $doNotFailOnPhpunitDeprecation, ?bool $doNotFailOnPhpunitNotice, ?bool $doNotFailOnPhpunitWarning, ?bool $doNotFailOnEmptyTestSuite, ?bool $doNotFailOnIncomplete, ?bool $doNotFailOnNotice, ?bool $doNotFailOnRisky, ?bool $doNotFailOnSkipped, ?bool $doNotFailOnWarning, ?int $stopOnDefect, ?int $stopOnDeprecation, ?string $specificDeprecationToStopOn, ?int $stopOnError, ?int $stopOnFailure, ?int $stopOnIncomplete, ?int $stopOnNotice, ?int $stopOnRisky, ?int $stopOnSkipped, ?int $stopOnWarning, ?string $filter, ?string $excludeFilter, ?string $generateBaseline, ?string $useBaseline, bool $ignoreBaseline, bool $generateConfiguration, bool $migrateConfiguration, bool $validateConfiguration, ?array $groups, ?array $testsCovering, ?array $testsUsing, ?array $testsRequiringPhpExtension, bool $help, ?string $includePath, ?array $iniSettings, ?string $junitLogfile, ?string $otrLogfile, ?bool $includeGitInformation, bool $listGroups, bool $listSuites, bool $listTestFiles, bool $listTestIds, bool $listTests, ?string $listTestsXml, ?bool $noCoverage, ?bool $noExtensions, ?bool $noOutput, ?bool $noProgress, ?bool $noResults, ?bool $noLogging, ?bool $processIsolation, ?int $randomOrderSeed, ?bool $reportUselessTests, ?bool $resolveDependencies, ?bool $reverseList, ?bool $stderr, ?bool $strictCoverage, ?bool $requireCoverageContribution, ?string $teamcityLogfile, ?string $testdoxHtmlFile, ?string $testdoxTextFile, ?array $testSuffixes, ?string $testSuite, ?string $excludeTestSuite, bool $useDefaultConfiguration, ?bool $displayDetailsOnAllIssues, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnPhpunitDeprecations, ?bool $displayDetailsOnPhpunitNotices, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerCompact, ?bool $printerTeamCity, ?bool $testdoxPrinter, ?bool $testdoxPrinterSummary, bool $debug, bool $withTelemetry, ?array $extensions) + public function __construct(array $arguments, ?string $testFilesFile, ?string $testIdFile, ?string $testIdFilter, ?bool $all, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, bool $checkPhpConfiguration, bool $checkVersion, ?string $colors, null|int|string $columns, ?string $configurationFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4J, ?string $coverageHtml, ?string $coverageOpenClover, ?string $coveragePhp, ?string $coverageText, ?bool $coverageTextShowUncoveredFiles, ?bool $coverageTextShowOnlySummary, ?string $coverageXml, ?bool $coverageXmlIncludeSource, ?bool $pathCoverage, ?bool $branchCoverage, bool $warmCoverageCache, ?int $defaultTimeLimit, ?int $diffContext, ?bool $disableCodeCoverageIgnore, ?bool $disableCoverageTargeting, ?bool $disallowTestOutput, ?bool $enforceTimeLimit, ?array $excludeGroups, ?int $executionOrder, ?int $executionOrderDefects, ?bool $failOnAllIssues, ?bool $failOnDeprecation, ?bool $failOnPhpunitDeprecation, ?bool $failOnPhpunitNotice, ?bool $failOnPhpunitWarning, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnNotice, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?bool $doNotFailOnDeprecation, ?bool $doNotFailOnPhpunitDeprecation, ?bool $doNotFailOnPhpunitNotice, ?bool $doNotFailOnPhpunitWarning, ?bool $doNotFailOnEmptyTestSuite, ?bool $doNotFailOnIncomplete, ?bool $doNotFailOnNotice, ?bool $doNotFailOnRisky, ?bool $doNotFailOnSkipped, ?bool $doNotFailOnWarning, ?int $stopOnDefect, ?int $stopOnDeprecation, ?string $specificDeprecationToStopOn, ?int $stopOnError, ?int $stopOnFailure, ?int $stopOnIncomplete, ?int $stopOnNotice, ?int $stopOnRisky, ?int $stopOnSkipped, ?int $stopOnWarning, ?string $filter, ?string $excludeFilter, ?string $generateBaseline, ?string $useBaseline, bool $ignoreBaseline, bool $generateConfiguration, bool $migrateConfiguration, bool $validateConfiguration, ?array $groups, ?array $testsCovering, ?array $testsUsing, ?array $testsRequiringPhpExtension, bool $help, ?string $includePath, ?array $iniSettings, ?string $junitLogfile, ?string $otrLogfile, ?bool $includeGitInformation, bool $listGroups, bool $listSuites, bool $listTestFiles, bool $listTestIds, bool $listTests, ?string $listTestsXml, ?bool $noCoverage, ?bool $noExtensions, ?bool $noOutput, ?bool $noProgress, ?bool $noResults, ?bool $noLogging, ?bool $processIsolation, ?int $randomOrderSeed, ?int $repeat, ?bool $reportUselessTests, ?bool $resolveDependencies, ?bool $reverseList, ?bool $stderr, ?bool $strictCoverage, ?bool $requireCoverageContribution, ?string $teamcityLogfile, ?string $testdoxHtmlFile, ?string $testdoxTextFile, ?array $testSuffixes, ?string $testSuite, ?string $excludeTestSuite, bool $useDefaultConfiguration, ?bool $displayDetailsOnAllIssues, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnPhpunitDeprecations, ?bool $displayDetailsOnPhpunitNotices, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerCompact, ?bool $printerTeamCity, ?bool $testdoxPrinter, ?bool $testdoxPrinterSummary, bool $debug, bool $withTelemetry, ?array $extensions) { $this->arguments = $arguments; $this->testFilesFile = $testFilesFile; @@ -317,6 +323,7 @@ public function __construct(array $arguments, ?string $testFilesFile, ?string $t $this->noLogging = $noLogging; $this->processIsolation = $processIsolation; $this->randomOrderSeed = $randomOrderSeed; + $this->repeat = $repeat; $this->reportUselessTests = $reportUselessTests; $this->resolveDependencies = $resolveDependencies; $this->reverseList = $reverseList; @@ -2240,6 +2247,28 @@ public function randomOrderSeed(): int return $this->randomOrderSeed; } + /** + * @phpstan-assert-if-true !null $this->repeat + */ + public function hasRepeat(): bool + { + return $this->repeat !== null; + } + + /** + * @throws Exception + * + * @return positive-int + */ + public function repeat(): int + { + if (!$this->hasRepeat()) { + throw new Exception; + } + + return $this->repeat; + } + /** * @phpstan-assert-if-true !null $this->reportUselessTests */ diff --git a/src/TextUI/Configuration/Configuration.php b/src/TextUI/Configuration/Configuration.php index 4ddb4809ca4..1ef00ad615f 100644 --- a/src/TextUI/Configuration/Configuration.php +++ b/src/TextUI/Configuration/Configuration.php @@ -432,6 +432,11 @@ * @var positive-int */ private int $randomOrderSeed; + + /** + * @var positive-int + */ + private int $repeat; private bool $includeUncoveredFiles; private TestSuiteCollection $testSuite; private string $includeTestSuite; @@ -535,13 +540,14 @@ * @param list $groups * @param list $excludeGroups * @param positive-int $randomOrderSeed + * @param positive-int $repeat * @param ?non-empty-string $defaultTestSuite * @param non-empty-list $testSuffixes * @param positive-int $numberOfTestsBeforeGarbageCollection * @param null|non-empty-string $generateBaseline * @param non-negative-int $shortenArraysForExportThreshold */ - public function __construct(array $cliArguments, ?string $testFilesFile, ?string $configurationFile, ?string $bootstrap, array $bootstrapForTestSuite, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, Source $source, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, string $coverageHtmlColorSuccessLow, string $coverageHtmlColorSuccessLowDark, string $coverageHtmlColorSuccessMedium, string $coverageHtmlColorSuccessMediumDark, string $coverageHtmlColorSuccessHigh, string $coverageHtmlColorSuccessHighDark, string $coverageHtmlColorSuccessBar, string $coverageHtmlColorSuccessBarDark, string $coverageHtmlColorWarning, string $coverageHtmlColorWarningDark, string $coverageHtmlColorWarningBar, string $coverageHtmlColorWarningBarDark, string $coverageHtmlColorDanger, string $coverageHtmlColorDangerDark, string $coverageHtmlColorDangerBar, string $coverageHtmlColorDangerBarDark, string $coverageHtmlColorBreadcrumbs, string $coverageHtmlColorBreadcrumbsDark, ?string $coverageHtmlCustomCssFile, ?string $coverageOpenClover, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $coverageXmlIncludeSource, bool $pathCoverage, bool $branchCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $disableCoverageTargeting, bool $failOnAllIssues, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnPhpunitNotice, bool $failOnPhpunitWarning, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $doNotFailOnDeprecation, bool $doNotFailOnPhpunitDeprecation, bool $doNotFailOnPhpunitNotice, bool $doNotFailOnPhpunitWarning, bool $doNotFailOnEmptyTestSuite, bool $doNotFailOnIncomplete, bool $doNotFailOnNotice, bool $doNotFailOnRisky, bool $doNotFailOnSkipped, bool $doNotFailOnWarning, int $stopOnDefect, int $stopOnDeprecation, ?string $specificDeprecationToStopOn, int $stopOnError, int $stopOnFailure, int $stopOnIncomplete, int $stopOnNotice, int $stopOnRisky, int $stopOnSkipped, int $stopOnWarning, bool $outputToStandardErrorStream, int $columns, bool $noExtensions, ?string $pharExtensionDirectory, array $extensionBootstrappers, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $processIsolation, bool $enforceTimeLimit, int $defaultTimeLimit, int $diffContext, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $requireCoverageContribution, bool $disallowTestOutput, bool $displayDetailsOnAllIssues, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnPhpunitNotices, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, bool $requireSealedMockObjects, bool $noProgress, bool $noResults, bool $noOutput, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileOtr, bool $includeGitInformation, bool $includeGitInformationInOtrLogfile, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logEventsText, ?string $logEventsVerboseText, bool $compactOutput, bool $teamCityOutput, bool $testDoxOutput, bool $testDoxOutputSummary, ?array $testsCovering, ?array $testsUsing, ?array $testsRequiringPhpExtension, ?string $filter, ?string $excludeFilter, ?string $testIdFilterFile, ?string $testIdFilter, array $groups, array $excludeGroups, int $randomOrderSeed, bool $includeUncoveredFiles, TestSuiteCollection $testSuite, string $includeTestSuite, string $excludeTestSuite, ?string $defaultTestSuite, bool $ignoreTestSelectionInXmlConfiguration, array $testSuffixes, Php $php, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection, ?string $generateBaseline, bool $debug, bool $withTelemetry, int $shortenArraysForExportThreshold) + public function __construct(array $cliArguments, ?string $testFilesFile, ?string $configurationFile, ?string $bootstrap, array $bootstrapForTestSuite, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, Source $source, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, string $coverageHtmlColorSuccessLow, string $coverageHtmlColorSuccessLowDark, string $coverageHtmlColorSuccessMedium, string $coverageHtmlColorSuccessMediumDark, string $coverageHtmlColorSuccessHigh, string $coverageHtmlColorSuccessHighDark, string $coverageHtmlColorSuccessBar, string $coverageHtmlColorSuccessBarDark, string $coverageHtmlColorWarning, string $coverageHtmlColorWarningDark, string $coverageHtmlColorWarningBar, string $coverageHtmlColorWarningBarDark, string $coverageHtmlColorDanger, string $coverageHtmlColorDangerDark, string $coverageHtmlColorDangerBar, string $coverageHtmlColorDangerBarDark, string $coverageHtmlColorBreadcrumbs, string $coverageHtmlColorBreadcrumbsDark, ?string $coverageHtmlCustomCssFile, ?string $coverageOpenClover, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $coverageXmlIncludeSource, bool $pathCoverage, bool $branchCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $disableCoverageTargeting, bool $failOnAllIssues, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnPhpunitNotice, bool $failOnPhpunitWarning, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $doNotFailOnDeprecation, bool $doNotFailOnPhpunitDeprecation, bool $doNotFailOnPhpunitNotice, bool $doNotFailOnPhpunitWarning, bool $doNotFailOnEmptyTestSuite, bool $doNotFailOnIncomplete, bool $doNotFailOnNotice, bool $doNotFailOnRisky, bool $doNotFailOnSkipped, bool $doNotFailOnWarning, int $stopOnDefect, int $stopOnDeprecation, ?string $specificDeprecationToStopOn, int $stopOnError, int $stopOnFailure, int $stopOnIncomplete, int $stopOnNotice, int $stopOnRisky, int $stopOnSkipped, int $stopOnWarning, bool $outputToStandardErrorStream, int $columns, bool $noExtensions, ?string $pharExtensionDirectory, array $extensionBootstrappers, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $processIsolation, bool $enforceTimeLimit, int $defaultTimeLimit, int $diffContext, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $requireCoverageContribution, bool $disallowTestOutput, bool $displayDetailsOnAllIssues, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnPhpunitNotices, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, bool $requireSealedMockObjects, bool $noProgress, bool $noResults, bool $noOutput, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileOtr, bool $includeGitInformation, bool $includeGitInformationInOtrLogfile, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logEventsText, ?string $logEventsVerboseText, bool $compactOutput, bool $teamCityOutput, bool $testDoxOutput, bool $testDoxOutputSummary, ?array $testsCovering, ?array $testsUsing, ?array $testsRequiringPhpExtension, ?string $filter, ?string $excludeFilter, ?string $testIdFilterFile, ?string $testIdFilter, array $groups, array $excludeGroups, int $randomOrderSeed, int $repeat, bool $includeUncoveredFiles, TestSuiteCollection $testSuite, string $includeTestSuite, string $excludeTestSuite, ?string $defaultTestSuite, bool $ignoreTestSelectionInXmlConfiguration, array $testSuffixes, Php $php, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection, ?string $generateBaseline, bool $debug, bool $withTelemetry, int $shortenArraysForExportThreshold) { $this->cliArguments = $cliArguments; $this->testFilesFile = $testFilesFile; @@ -683,6 +689,7 @@ public function __construct(array $cliArguments, ?string $testFilesFile, ?string $this->groups = $groups; $this->excludeGroups = $excludeGroups; $this->randomOrderSeed = $randomOrderSeed; + $this->repeat = $repeat; $this->includeUncoveredFiles = $includeUncoveredFiles; $this->testSuite = $testSuite; $this->includeTestSuite = $includeTestSuite; @@ -2164,6 +2171,14 @@ public function randomOrderSeed(): int return $this->randomOrderSeed; } + /** + * @return positive-int + */ + public function repeat(): int + { + return $this->repeat; + } + public function includeUncoveredFiles(): bool { return $this->includeUncoveredFiles; diff --git a/src/TextUI/Configuration/Merger.php b/src/TextUI/Configuration/Merger.php index b87dd0ff612..ec70c7996a9 100644 --- a/src/TextUI/Configuration/Merger.php +++ b/src/TextUI/Configuration/Merger.php @@ -912,6 +912,12 @@ public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlC $randomOrderSeed = time(); } + $repeat = 1; + + if ($cliConfiguration->hasRepeat()) { + $repeat = $cliConfiguration->repeat(); + } + if ($xmlConfiguration->wasLoadedFromFile() && $xmlConfiguration->hasValidationErrors()) { if ((new SchemaDetector)->detect($xmlConfiguration->filename())->detected()) { EventFacade::emitter()->testRunnerTriggeredPhpunitDeprecation( @@ -1282,6 +1288,7 @@ public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlC $groups, $excludeGroups, $randomOrderSeed, + $repeat, $includeUncoveredFiles, $xmlConfiguration->testSuite(), $includeTestSuite, diff --git a/src/TextUI/Configuration/TestSuiteBuilder.php b/src/TextUI/Configuration/TestSuiteBuilder.php index 44cc0b71212..039be174b3f 100644 --- a/src/TextUI/Configuration/TestSuiteBuilder.php +++ b/src/TextUI/Configuration/TestSuiteBuilder.php @@ -45,6 +45,8 @@ */ public function build(Configuration $configuration): TestSuite { + $numberOfRuns = $configuration->repeat(); + if ($configuration->hasCliArguments() || $configuration->hasTestFilesFile()) { $arguments = []; @@ -95,11 +97,13 @@ public function build(Configuration $configuration): TestSuite $testSuite = $this->testSuiteFromPath( $arguments[0], $configuration->testSuffixes(), + $numberOfRuns, ); } else { $testSuite = $this->testSuiteFromPathList( $arguments, $configuration->testSuffixes(), + $numberOfRuns, ); } } @@ -114,6 +118,7 @@ public function build(Configuration $configuration): TestSuite $configuration->testSuite(), $configuration->ignoreTestSelectionInXmlConfiguration() ? [] : $configuration->includeTestSuites(), $configuration->ignoreTestSelectionInXmlConfiguration() ? [] : $configuration->excludeTestSuites(), + $numberOfRuns, ); } @@ -125,17 +130,18 @@ public function build(Configuration $configuration): TestSuite /** * @param non-empty-string $path * @param list $suffixes + * @param positive-int $numberOfRuns * * @throws \PHPUnit\Framework\Exception */ - private function testSuiteFromPath(string $path, array $suffixes, ?TestSuite $suite = null): TestSuite + private function testSuiteFromPath(string $path, array $suffixes, int $numberOfRuns, ?TestSuite $suite = null): TestSuite { if (str_ends_with($path, '.phpt') && is_file($path)) { if ($suite === null) { $suite = TestSuite::empty($path); } - $suite->addTestFile($path); + $suite->addTestFile($path, [], $numberOfRuns); return $suite; } @@ -147,7 +153,7 @@ private function testSuiteFromPath(string $path, array $suffixes, ?TestSuite $su $suite = TestSuite::empty('CLI Arguments'); } - $suite->addTestFiles($files); + $suite->addTestFiles($files, $numberOfRuns); return $suite; } @@ -161,10 +167,10 @@ private function testSuiteFromPath(string $path, array $suffixes, ?TestSuite $su } if ($suite === null) { - return TestSuite::fromClassReflector($testClass); + return TestSuite::fromClassReflector($testClass, [], $numberOfRuns); } - $suite->addTestSuite($testClass); + $suite->addTestSuite($testClass, [], $numberOfRuns); return $suite; } @@ -172,15 +178,16 @@ private function testSuiteFromPath(string $path, array $suffixes, ?TestSuite $su /** * @param list $paths * @param list $suffixes + * @param positive-int $numberOfRuns * * @throws \PHPUnit\Framework\Exception */ - private function testSuiteFromPathList(array $paths, array $suffixes): TestSuite + private function testSuiteFromPathList(array $paths, array $suffixes, int $numberOfRuns): TestSuite { $suite = TestSuite::empty('CLI Arguments'); foreach ($paths as $path) { - $this->testSuiteFromPath($path, $suffixes, $suite); + $this->testSuiteFromPath($path, $suffixes, $numberOfRuns, $suite); } return $suite; diff --git a/src/TextUI/Configuration/Xml/TestSuiteMapper.php b/src/TextUI/Configuration/Xml/TestSuiteMapper.php index 66bd611c1c6..61c99d62590 100644 --- a/src/TextUI/Configuration/Xml/TestSuiteMapper.php +++ b/src/TextUI/Configuration/Xml/TestSuiteMapper.php @@ -36,12 +36,13 @@ * @param non-empty-string $xmlConfigurationFile * @param list $includeTestSuites * @param list $excludeTestSuites + * @param positive-int $numberOfRuns * * @throws RuntimeException * @throws TestDirectoryNotFoundException * @throws TestFileNotFoundException */ - public function map(string $xmlConfigurationFile, TestSuiteCollection $configuredTestSuites, array $includeTestSuites, array $excludeTestSuites): TestSuiteObject + public function map(string $xmlConfigurationFile, TestSuiteCollection $configuredTestSuites, array $includeTestSuites, array $excludeTestSuites, int $numberOfRuns = 1): TestSuiteObject { try { $result = TestSuiteObject::empty($xmlConfigurationFile); @@ -101,7 +102,7 @@ public function map(string $xmlConfigurationFile, TestSuiteCollection $configure $processed[$file] = $testSuiteName; $empty = false; - $testSuite->addTestFile($file, $groups); + $testSuite->addTestFile($file, $groups, $numberOfRuns); } } @@ -130,7 +131,7 @@ public function map(string $xmlConfigurationFile, TestSuiteCollection $configure $processed[$file->path()] = $testSuiteName; $empty = false; - $testSuite->addTestFile($file->path(), $file->groups()); + $testSuite->addTestFile($file->path(), $file->groups(), $numberOfRuns); } if (!$empty) { diff --git a/src/TextUI/Help.php b/src/TextUI/Help.php index 3bda4b78ebd..1ae49d06513 100644 --- a/src/TextUI/Help.php +++ b/src/TextUI/Help.php @@ -272,6 +272,7 @@ private function elements(): array ['arg' => '--ignore-dependencies', 'desc' => 'Alias for "--order-by no-depends"'], ['arg' => '--random-order', 'desc' => 'Alias for "--order-by random"'], ['arg' => '--random-order-seed ', 'desc' => 'Use the specified random seed when running tests in random order'], + ['arg' => '--repeat ', 'desc' => 'Run each test N times, stopping at the first failure'], ['arg' => '--reverse-order', 'desc' => 'Alias for "--order-by reverse"'], ], diff --git a/tests/_files/Metadata/Attribute/tests/RepeatTest.php b/tests/_files/Metadata/Attribute/tests/RepeatTest.php new file mode 100644 index 00000000000..1cc98494545 --- /dev/null +++ b/tests/_files/Metadata/Attribute/tests/RepeatTest.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Metadata\Attribute; + +use PHPUnit\Framework\Attributes\Repeat; +use PHPUnit\Framework\TestCase; + +final class RepeatTest extends TestCase +{ + #[Repeat(5, failureThreshold: 2)] + public function testOne(): void + { + } +} diff --git a/tests/end-to-end/_files/output-cli-help-color.txt b/tests/end-to-end/_files/output-cli-help-color.txt index 4389f4f4ec6..2e9c7f3e452 100644 --- a/tests/end-to-end/_files/output-cli-help-color.txt +++ b/tests/end-to-end/_files/output-cli-help-color.txt @@ -149,6 +149,8 @@ --random-order  Alias for "--order-by random" --random-order-seed   Use the specified random seed when running tests in random order + --repeat   Run each test N times, stopping at the + first failure --reverse-order  Alias for "--order-by reverse" Reporting: diff --git a/tests/end-to-end/_files/output-cli-usage.txt b/tests/end-to-end/_files/output-cli-usage.txt index f390f71b4b8..9b7e12b9305 100644 --- a/tests/end-to-end/_files/output-cli-usage.txt +++ b/tests/end-to-end/_files/output-cli-usage.txt @@ -98,6 +98,7 @@ Execution: --ignore-dependencies Alias for "--order-by no-depends" --random-order Alias for "--order-by random" --random-order-seed Use the specified random seed when running tests in random order + --repeat Run each test N times, stopping at the first failure --reverse-order Alias for "--order-by reverse" Reporting: diff --git a/tests/end-to-end/cli/filter/filter-empty-method-portion-keeps-all-providers.phpt b/tests/end-to-end/cli/filter/filter-empty-method-portion-keeps-all-providers.phpt index 2854419366f..001daaa59ff 100644 --- a/tests/end-to-end/cli/filter/filter-empty-method-portion-keeps-all-providers.phpt +++ b/tests/end-to-end/cli/filter/filter-empty-method-portion-keeps-all-providers.phpt @@ -28,18 +28,18 @@ Test Suite Sorted Test Suite Filtered (2 tests) Test Runner Execution Started (2 tests) Test Suite Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest, 2 tests) -Test Suite Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 1 test) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 1 data set) Test Preparation Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) Test Prepared (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) Test Passed (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) Test Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) -Test Suite Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 1 test) -Test Suite Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testB, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 1 data set) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testB, 1 data set) Test Preparation Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testB#1) Test Prepared (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testB#1) Test Passed (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testB#1) Test Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testB#1) -Test Suite Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testB, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testB, 1 data set) Test Suite Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest, 2 tests) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/cli/filter/filter-explicit-regex-keeps-all-providers.phpt b/tests/end-to-end/cli/filter/filter-explicit-regex-keeps-all-providers.phpt index 0ad3c6529c0..cebb887dcaf 100644 --- a/tests/end-to-end/cli/filter/filter-explicit-regex-keeps-all-providers.phpt +++ b/tests/end-to-end/cli/filter/filter-explicit-regex-keeps-all-providers.phpt @@ -28,7 +28,7 @@ Test Suite Sorted Test Suite Filtered (2 tests) Test Runner Execution Started (2 tests) Test Suite Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest, 2 tests) -Test Suite Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 2 tests) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 2 data sets) Test Preparation Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#0) Test Prepared (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#0) Test Passed (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#0) @@ -37,7 +37,7 @@ Test Preparation Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest:: Test Prepared (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) Test Passed (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) Test Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) -Test Suite Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 2 tests) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 2 data sets) Test Suite Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest, 2 tests) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/cli/filter/filter-skips-data-provider-for-non-matching-method.phpt b/tests/end-to-end/cli/filter/filter-skips-data-provider-for-non-matching-method.phpt index 317561f796d..271956a32a2 100644 --- a/tests/end-to-end/cli/filter/filter-skips-data-provider-for-non-matching-method.phpt +++ b/tests/end-to-end/cli/filter/filter-skips-data-provider-for-non-matching-method.phpt @@ -25,7 +25,7 @@ Test Suite Sorted Test Suite Filtered (2 tests) Test Runner Execution Started (2 tests) Test Suite Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest, 2 tests) -Test Suite Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 2 tests) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 2 data sets) Test Preparation Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#0) Test Prepared (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#0) Test Passed (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#0) @@ -34,7 +34,7 @@ Test Preparation Started (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest:: Test Prepared (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) Test Passed (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) Test Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA#1) -Test Suite Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 2 tests) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest::testA, 2 data sets) Test Suite Finished (PHPUnit\TestFixture\DataProviderSkipWhenFilteredTest, 2 tests) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/cli/test-id-filter/test-id-filter-by-id-with-special-characters.phpt b/tests/end-to-end/cli/test-id-filter/test-id-filter-by-id-with-special-characters.phpt index dcf79b8ad7e..31025272477 100644 --- a/tests/end-to-end/cli/test-id-filter/test-id-filter-by-id-with-special-characters.phpt +++ b/tests/end-to-end/cli/test-id-filter/test-id-filter-by-id-with-special-characters.phpt @@ -25,12 +25,12 @@ Test Suite Sorted Test Suite Filtered (1 test) Test Runner Execution Started (1 test) Test Suite Started (PHPUnit\TestFixture\TestIdFilter\BarTest, 1 test) -Test Suite Started (PHPUnit\TestFixture\TestIdFilter\BarTest::testWithSpecialCharacters, 1 test) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\TestIdFilter\BarTest::testWithSpecialCharacters, 1 data set) Test Preparation Started (PHPUnit\TestFixture\TestIdFilter\BarTest::testWithSpecialCharacters#total ($100)) Test Prepared (PHPUnit\TestFixture\TestIdFilter\BarTest::testWithSpecialCharacters#total ($100)) Test Passed (PHPUnit\TestFixture\TestIdFilter\BarTest::testWithSpecialCharacters#total ($100)) Test Finished (PHPUnit\TestFixture\TestIdFilter\BarTest::testWithSpecialCharacters#total ($100)) -Test Suite Finished (PHPUnit\TestFixture\TestIdFilter\BarTest::testWithSpecialCharacters, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\TestIdFilter\BarTest::testWithSpecialCharacters, 1 data set) Test Suite Finished (PHPUnit\TestFixture\TestIdFilter\BarTest, 1 test) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/event/data-provider-external.phpt b/tests/end-to-end/event/data-provider-external.phpt index 03ff9791292..9aa408e6538 100644 --- a/tests/end-to-end/event/data-provider-external.phpt +++ b/tests/end-to-end/event/data-provider-external.phpt @@ -25,7 +25,7 @@ Test Runner Started Test Suite Sorted Test Runner Execution Started (2 tests) Test Suite Started (PHPUnit\TestFixture\Event\DataProviderExternalTest, 2 tests) -Test Suite Started (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess, 2 tests) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess, 2 data sets) Test Preparation Started (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess#0) Test Prepared (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess#0) Test Passed (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess#0) @@ -34,7 +34,7 @@ Test Preparation Started (PHPUnit\TestFixture\Event\DataProviderExternalTest::te Test Prepared (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess#1) Test Passed (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess#1) Test Finished (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess#1) -Test Suite Finished (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess, 2 tests) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Event\DataProviderExternalTest::testSuccess, 2 data sets) Test Suite Finished (PHPUnit\TestFixture\Event\DataProviderExternalTest, 2 tests) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/event/data-provider-in-parent-class.phpt b/tests/end-to-end/event/data-provider-in-parent-class.phpt index 9a96a36329c..b03a20e5bc3 100644 --- a/tests/end-to-end/event/data-provider-in-parent-class.phpt +++ b/tests/end-to-end/event/data-provider-in-parent-class.phpt @@ -22,12 +22,12 @@ Test Runner Started Test Suite Sorted Test Runner Execution Started (1 test) Test Suite Started (PHPUnit\TestFixture\Event\DataProviderInParentTest, 1 test) -Test Suite Started (PHPUnit\TestFixture\Event\DataProviderInParentTest::testSomething, 1 test) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Event\DataProviderInParentTest::testSomething, 1 data set) Test Preparation Started (PHPUnit\TestFixture\Event\DataProviderInParentTest::testSomething#0) Test Prepared (PHPUnit\TestFixture\Event\DataProviderInParentTest::testSomething#0) Test Passed (PHPUnit\TestFixture\Event\DataProviderInParentTest::testSomething#0) Test Finished (PHPUnit\TestFixture\Event\DataProviderInParentTest::testSomething#0) -Test Suite Finished (PHPUnit\TestFixture\Event\DataProviderInParentTest::testSomething, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Event\DataProviderInParentTest::testSomething, 1 data set) Test Suite Finished (PHPUnit\TestFixture\Event\DataProviderInParentTest, 1 test) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/event/data-provider-invalid-argument-name.phpt b/tests/end-to-end/event/data-provider-invalid-argument-name.phpt index d5b8b946f5b..1d61749ae98 100644 --- a/tests/end-to-end/event/data-provider-invalid-argument-name.phpt +++ b/tests/end-to-end/event/data-provider-invalid-argument-name.phpt @@ -22,7 +22,7 @@ Test Runner Started Test Suite Sorted Test Runner Execution Started (2 tests) Test Suite Started (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest, 2 tests) -Test Suite Started (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess, 2 tests) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess, 2 data sets) Test Preparation Started (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#0) Test Prepared (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#0) Test Passed (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#0) @@ -32,7 +32,7 @@ Test Prepared (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::t Test Errored (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#1) Unknown named parameter $value3 Test Finished (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#1) -Test Suite Finished (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess, 2 tests) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess, 2 data sets) Test Suite Finished (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest, 2 tests) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/event/data-provider.phpt b/tests/end-to-end/event/data-provider.phpt index f50444ec77a..3188caf5abe 100644 --- a/tests/end-to-end/event/data-provider.phpt +++ b/tests/end-to-end/event/data-provider.phpt @@ -22,7 +22,7 @@ Test Runner Started Test Suite Sorted Test Runner Execution Started (2 tests) Test Suite Started (PHPUnit\TestFixture\Event\DataProviderTest, 2 tests) -Test Suite Started (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess, 2 tests) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess, 2 data sets) Test Preparation Started (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess#0) Test Prepared (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess#0) Test Passed (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess#0) @@ -31,7 +31,7 @@ Test Preparation Started (PHPUnit\TestFixture\Event\DataProviderTest::testSucces Test Prepared (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess#1) Test Passed (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess#1) Test Finished (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess#1) -Test Suite Finished (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess, 2 tests) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Event\DataProviderTest::testSuccess, 2 data sets) Test Suite Finished (PHPUnit\TestFixture\Event\DataProviderTest, 2 tests) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/event/testwith-attribute-too-many-values.phpt b/tests/end-to-end/event/testwith-attribute-too-many-values.phpt index 6255dd60b25..2917bc2d930 100644 --- a/tests/end-to-end/event/testwith-attribute-too-many-values.phpt +++ b/tests/end-to-end/event/testwith-attribute-too-many-values.phpt @@ -21,12 +21,12 @@ Test Runner Started Test Suite Sorted Test Runner Execution Started (1 test) Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest, 1 test) -Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest::testOne, 1 test) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest::testOne, 1 data set) Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest::testOne#0) Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest::testOne#0) Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest::testOne#0) Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest::testOne#0) -Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest::testOne, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest::testOne, 1 data set) Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTooManyValuesTest, 1 test) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/event/testwith-attribute.phpt b/tests/end-to-end/event/testwith-attribute.phpt index d5761afdc7c..ee394d93446 100644 --- a/tests/end-to-end/event/testwith-attribute.phpt +++ b/tests/end-to-end/event/testwith-attribute.phpt @@ -19,30 +19,30 @@ Test Runner Started Test Suite Sorted Test Runner Execution Started (4 tests) Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest, 4 tests) -Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne, 1 test) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne, 1 data set) Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne#0) Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne#0) Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne#0) Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne#0) -Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne, 1 test) -Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOneWithName, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne, 1 data set) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOneWithName, 1 data set) Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOneWithName#Name1) Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOneWithName#Name1) Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOneWithName#Name1) Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOneWithName#Name1) -Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOneWithName, 1 test) -Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwo, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOneWithName, 1 data set) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwo, 1 data set) Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwo#0) Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwo#0) Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwo#0) Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwo#0) -Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwo, 1 test) -Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwo, 1 data set) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName, 1 data set) Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName#Name2) Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName#Name2) Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName#Name2) Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName#Name2) -Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName, 1 data set) Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest, 4 tests) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/regression/4975.phpt b/tests/end-to-end/regression/4975.phpt index aa898dd2499..1cc05f6444a 100644 --- a/tests/end-to-end/regression/4975.phpt +++ b/tests/end-to-end/regression/4975.phpt @@ -24,12 +24,12 @@ Test Suite Sorted Test Suite Filtered (1 test) Test Runner Execution Started (1 test) Test Suite Started (PHPUnit\TestFixture\Issue4975Test, 1 test) -Test Suite Started (PHPUnit\TestFixture\Issue4975Test::testSomething, 1 test) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Issue4975Test::testSomething, 1 data set) Test Preparation Started (PHPUnit\TestFixture\Issue4975Test::testSomething##2 second) Test Prepared (PHPUnit\TestFixture\Issue4975Test::testSomething##2 second) Test Passed (PHPUnit\TestFixture\Issue4975Test::testSomething##2 second) Test Finished (PHPUnit\TestFixture\Issue4975Test::testSomething##2 second) -Test Suite Finished (PHPUnit\TestFixture\Issue4975Test::testSomething, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Issue4975Test::testSomething, 1 data set) Test Suite Finished (PHPUnit\TestFixture\Issue4975Test, 1 test) Test Runner Execution Finished Test Runner Finished diff --git a/tests/end-to-end/regression/5287.phpt b/tests/end-to-end/regression/5287.phpt index db0517cd433..8c9acdfbd12 100644 --- a/tests/end-to-end/regression/5287.phpt +++ b/tests/end-to-end/regression/5287.phpt @@ -26,12 +26,12 @@ Test Suite Sorted Test Runner Execution Started (3 tests) Test Suite Started (CLI Arguments, 3 tests) Test Suite Started (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest, 1 test) -Test Suite Started (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest::test, 1 test) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest::test, 1 data set) Test Preparation Started (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest::test#0) Test Prepared (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest::test#0) Test Passed (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest::test#0) Test Finished (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest::test#0) -Test Suite Finished (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest::test, 1 test) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest::test, 1 data set) Test Suite Finished (PHPUnit\TestFixture\Issue5278\A\AnotherClassTest, 1 test) Test Suite Started (PHPUnit\TestFixture\Issue5278\B\MyClassTest, 1 test) Test Preparation Started (PHPUnit\TestFixture\Issue5278\B\MyClassTest::test) diff --git a/tests/end-to-end/repeat/_files/DataProviderTest.php b/tests/end-to-end/repeat/_files/DataProviderTest.php new file mode 100644 index 00000000000..39d0b696320 --- /dev/null +++ b/tests/end-to-end/repeat/_files/DataProviderTest.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\TestCase; + +final class DataProviderTest extends TestCase +{ + public static function provider(): array + { + return [ + 'one' => [1], + 'two' => [2], + ]; + } + + #[DataProvider('provider')] + public function testWithDataProvider(int $value): void + { + $this->assertGreaterThan(0, $value); + } +} diff --git a/tests/end-to-end/repeat/_files/DependsTest.php b/tests/end-to-end/repeat/_files/DependsTest.php new file mode 100644 index 00000000000..1ac752726ce --- /dev/null +++ b/tests/end-to-end/repeat/_files/DependsTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\Attributes\Depends; +use PHPUnit\Framework\TestCase; + +final class DependsTest extends TestCase +{ + public function testOne(): void + { + $this->assertTrue(true); + } + + #[Depends('testOne')] + public function testTwo(): void + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/FailureOnSecondRepetitionTest.php b/tests/end-to-end/repeat/_files/FailureOnSecondRepetitionTest.php new file mode 100644 index 00000000000..a842627a970 --- /dev/null +++ b/tests/end-to-end/repeat/_files/FailureOnSecondRepetitionTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\TestCase; + +final class FailureOnSecondRepetitionTest extends TestCase +{ + private static int $count = 0; + + public function testOne(): void + { + self::$count++; + + if (self::$count === 2) { + $this->fail('Failure on second repetition'); + } + + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/NoReturnTypeTest.php b/tests/end-to-end/repeat/_files/NoReturnTypeTest.php new file mode 100644 index 00000000000..ec589dbb619 --- /dev/null +++ b/tests/end-to-end/repeat/_files/NoReturnTypeTest.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\TestCase; + +final class NoReturnTypeTest extends TestCase +{ + /** @phpstan-ignore missingType.return */ + public function testWithoutReturnType() + { + $this->assertTrue(true); + } + + public function testWithVoidReturn(): void + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/NonVoidReturnTest.php b/tests/end-to-end/repeat/_files/NonVoidReturnTest.php new file mode 100644 index 00000000000..7568bbcdf7b --- /dev/null +++ b/tests/end-to-end/repeat/_files/NonVoidReturnTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\TestCase; + +final class NonVoidReturnTest extends TestCase +{ + public function testWithReturnValue(): int + { + $this->assertTrue(true); + + return 1; + } + + public function testWithVoidReturn(): void + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/RepeatAttributeOnDependentTest.php b/tests/end-to-end/repeat/_files/RepeatAttributeOnDependentTest.php new file mode 100644 index 00000000000..1cbf1fbbb31 --- /dev/null +++ b/tests/end-to-end/repeat/_files/RepeatAttributeOnDependentTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\Attributes\Depends; +use PHPUnit\Framework\Attributes\Repeat; +use PHPUnit\Framework\TestCase; + +final class RepeatAttributeOnDependentTest extends TestCase +{ + public function testOne(): void + { + $this->assertTrue(true); + } + + #[Depends('testOne')] + #[Repeat(3)] + public function testTwo(): void + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/RepeatAttributeOnNonVoidReturnTest.php b/tests/end-to-end/repeat/_files/RepeatAttributeOnNonVoidReturnTest.php new file mode 100644 index 00000000000..d5b307e4f83 --- /dev/null +++ b/tests/end-to-end/repeat/_files/RepeatAttributeOnNonVoidReturnTest.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\Attributes\Repeat; +use PHPUnit\Framework\TestCase; + +final class RepeatAttributeOnNonVoidReturnTest extends TestCase +{ + #[Repeat(3)] + public function testWithReturnValue(): int + { + $this->assertTrue(true); + + return 1; + } +} diff --git a/tests/end-to-end/repeat/_files/RepeatAttributeOverrideTest.php b/tests/end-to-end/repeat/_files/RepeatAttributeOverrideTest.php new file mode 100644 index 00000000000..167d1d88d47 --- /dev/null +++ b/tests/end-to-end/repeat/_files/RepeatAttributeOverrideTest.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\Attributes\Repeat; +use PHPUnit\Framework\TestCase; + +final class RepeatAttributeOverrideTest extends TestCase +{ + #[Repeat(2)] + public function testAttributeOverridesCliRepeat(): void + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/RepeatAttributeTest.php b/tests/end-to-end/repeat/_files/RepeatAttributeTest.php new file mode 100644 index 00000000000..d4243286330 --- /dev/null +++ b/tests/end-to-end/repeat/_files/RepeatAttributeTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\Attributes\Repeat; +use PHPUnit\Framework\TestCase; + +final class RepeatAttributeTest extends TestCase +{ + #[Repeat(3)] + public function testRepeatedThreeTimes(): void + { + $this->assertTrue(true); + } + + public function testNotRepeated(): void + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/RepeatAttributeWithoutReturnTypeTest.php b/tests/end-to-end/repeat/_files/RepeatAttributeWithoutReturnTypeTest.php new file mode 100644 index 00000000000..e2b425dde2a --- /dev/null +++ b/tests/end-to-end/repeat/_files/RepeatAttributeWithoutReturnTypeTest.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\Attributes\Repeat; +use PHPUnit\Framework\TestCase; + +final class RepeatAttributeWithoutReturnTypeTest extends TestCase +{ + #[Repeat(3)] + public function testWithoutReturnType() + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/SuccessTest.php b/tests/end-to-end/repeat/_files/SuccessTest.php new file mode 100644 index 00000000000..413c3acd975 --- /dev/null +++ b/tests/end-to-end/repeat/_files/SuccessTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\TestCase; + +final class SuccessTest extends TestCase +{ + public function testOne(): void + { + $this->assertTrue(true); + } + + public function testTwo(): void + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/_files/UnionReturnTypeTest.php b/tests/end-to-end/repeat/_files/UnionReturnTypeTest.php new file mode 100644 index 00000000000..864f4d6890d --- /dev/null +++ b/tests/end-to-end/repeat/_files/UnionReturnTypeTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Repeat; + +use PHPUnit\Framework\TestCase; + +final class UnionReturnTypeTest extends TestCase +{ + public function testWithUnionReturnType(): int|string + { + $this->assertTrue(true); + + return 1; + } + + public function testWithVoidReturn(): void + { + $this->assertTrue(true); + } +} diff --git a/tests/end-to-end/repeat/repeat-attribute-overrides-cli.phpt b/tests/end-to-end/repeat/repeat-attribute-overrides-cli.phpt new file mode 100644 index 00000000000..d68dc0ea77b --- /dev/null +++ b/tests/end-to-end/repeat/repeat-attribute-overrides-cli.phpt @@ -0,0 +1,37 @@ +--TEST-- +#[Repeat] attribute takes precedence over --repeat CLI option +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (2 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (2 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest, 2 tests) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest::testAttributeOverridesCliRepeat, 2 repetitions) +Test Suite Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOverrideTest, 2 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-attribute-warning-depends.phpt b/tests/end-to-end/repeat/repeat-attribute-warning-depends.phpt new file mode 100644 index 00000000000..c9421bd013e --- /dev/null +++ b/tests/end-to-end/repeat/repeat-attribute-warning-depends.phpt @@ -0,0 +1,34 @@ +--TEST-- +#[Repeat] on method that depends on another test triggers a test runner warning +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Runner Triggered PHPUnit Warning (Method PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testTwo is annotated with #[Repeat] but depends on another test and will not be repeated) +Test Suite Loaded (2 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (2 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest, 2 tests) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testOne) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testOne) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testOne) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testOne) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testTwo) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testTwo) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testTwo) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest::testTwo) +Test Suite Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOnDependentTest, 2 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 1) diff --git a/tests/end-to-end/repeat/repeat-attribute-warning-no-return-type.phpt b/tests/end-to-end/repeat/repeat-attribute-warning-no-return-type.phpt new file mode 100644 index 00000000000..850bd50cc3c --- /dev/null +++ b/tests/end-to-end/repeat/repeat-attribute-warning-no-return-type.phpt @@ -0,0 +1,30 @@ +--TEST-- +#[Repeat] on method without return type declaration triggers a test runner warning +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Runner Triggered PHPUnit Warning (Method PHPUnit\TestFixture\Repeat\RepeatAttributeWithoutReturnTypeTest::testWithoutReturnType is annotated with #[Repeat] but does not have a void return type declaration and will not be repeated) +Test Suite Loaded (1 test) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (1 test) +Test Suite Started (PHPUnit\TestFixture\Repeat\RepeatAttributeWithoutReturnTypeTest, 1 test) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeWithoutReturnTypeTest::testWithoutReturnType) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeWithoutReturnTypeTest::testWithoutReturnType) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeWithoutReturnTypeTest::testWithoutReturnType) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeWithoutReturnTypeTest::testWithoutReturnType) +Test Suite Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeWithoutReturnTypeTest, 1 test) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 1) diff --git a/tests/end-to-end/repeat/repeat-attribute-warning-non-void-return.phpt b/tests/end-to-end/repeat/repeat-attribute-warning-non-void-return.phpt new file mode 100644 index 00000000000..704fb754a0b --- /dev/null +++ b/tests/end-to-end/repeat/repeat-attribute-warning-non-void-return.phpt @@ -0,0 +1,30 @@ +--TEST-- +#[Repeat] on method with non-void return type triggers a test runner warning +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Runner Triggered PHPUnit Warning (Method PHPUnit\TestFixture\Repeat\RepeatAttributeOnNonVoidReturnTest::testWithReturnValue is annotated with #[Repeat] but does not have a void return type declaration and will not be repeated) +Test Suite Loaded (1 test) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (1 test) +Test Suite Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOnNonVoidReturnTest, 1 test) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeOnNonVoidReturnTest::testWithReturnValue) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeOnNonVoidReturnTest::testWithReturnValue) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeOnNonVoidReturnTest::testWithReturnValue) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOnNonVoidReturnTest::testWithReturnValue) +Test Suite Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeOnNonVoidReturnTest, 1 test) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 1) diff --git a/tests/end-to-end/repeat/repeat-attribute.phpt b/tests/end-to-end/repeat/repeat-attribute.phpt new file mode 100644 index 00000000000..fe75c4472a0 --- /dev/null +++ b/tests/end-to-end/repeat/repeat-attribute.phpt @@ -0,0 +1,43 @@ +--TEST-- +#[Repeat] attribute repeats individual test method +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (4 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (4 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\RepeatAttributeTest, 4 tests) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes, 3 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 1 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 1 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 1 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 1 of 3)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 2 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 2 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 2 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 2 of 3)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 3 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 3 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 3 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes (repetition 3 of 3)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testRepeatedThreeTimes, 3 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testNotRepeated) +Test Prepared (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testNotRepeated) +Test Passed (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testNotRepeated) +Test Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeTest::testNotRepeated) +Test Suite Finished (PHPUnit\TestFixture\Repeat\RepeatAttributeTest, 4 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-failure-stops-repetitions.phpt b/tests/end-to-end/repeat/repeat-failure-stops-repetitions.phpt new file mode 100644 index 00000000000..2ea390050af --- /dev/null +++ b/tests/end-to-end/repeat/repeat-failure-stops-repetitions.phpt @@ -0,0 +1,40 @@ +--TEST-- +--repeat stops remaining repetitions after failure +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (3 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (3 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest, 3 tests) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne, 3 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 1 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 1 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 1 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 1 of 3)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 2 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 2 of 3)) +Test Failed (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 2 of 3)) +Failure on second repetition +Test Finished (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 2 of 3)) +Test Skipped (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne (repetition 3 of 3)) +Remaining repetition skipped after failure in repetition 2 +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest::testOne, 3 repetitions) +Test Suite Finished (PHPUnit\TestFixture\Repeat\FailureOnSecondRepetitionTest, 3 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 1) diff --git a/tests/end-to-end/repeat/repeat-invalid-value.phpt b/tests/end-to-end/repeat/repeat-invalid-value.phpt new file mode 100644 index 00000000000..903aae72385 --- /dev/null +++ b/tests/end-to-end/repeat/repeat-invalid-value.phpt @@ -0,0 +1,36 @@ +--TEST-- +--repeat with invalid value triggers warning +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Triggered PHPUnit Warning (Option "--repeat 0" ignored because "0" is not a positive integer) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (2 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (2 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\SuccessTest, 2 tests) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testOne) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testOne) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo) +Test Suite Finished (PHPUnit\TestFixture\Repeat\SuccessTest, 2 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 1) diff --git a/tests/end-to-end/repeat/repeat-junit-xml-logging.phpt b/tests/end-to-end/repeat/repeat-junit-xml-logging.phpt new file mode 100644 index 00000000000..450a0d10499 --- /dev/null +++ b/tests/end-to-end/repeat/repeat-junit-xml-logging.phpt @@ -0,0 +1,44 @@ +--TEST-- +--repeat with JUnit XML logging includes repetition info in test names +--FILE-- +run($_SERVER['argv']); + +print file_get_contents($junitFile); + +unlink($junitFile); +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s + +.... 4 / 4 (100%) + +Time: %s, Memory: %s + +OK (4 tests, 4 assertions) + + + + + + + + + + + + + diff --git a/tests/end-to-end/repeat/repeat-skips-dependent-test.phpt b/tests/end-to-end/repeat/repeat-skips-dependent-test.phpt new file mode 100644 index 00000000000..7f10476e489 --- /dev/null +++ b/tests/end-to-end/repeat/repeat-skips-dependent-test.phpt @@ -0,0 +1,41 @@ +--TEST-- +--repeat does not repeat test that depends on another test +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (3 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (3 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\DependsTest, 3 tests) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\DependsTest::testOne, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\DependsTest::testOne (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\DependsTest::testOne (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\DependsTest::testOne (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\DependsTest::testOne (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\DependsTest::testOne (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\DependsTest::testOne (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\DependsTest::testOne (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\DependsTest::testOne (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\DependsTest::testOne, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\DependsTest::testTwo) +Test Prepared (PHPUnit\TestFixture\Repeat\DependsTest::testTwo) +Test Passed (PHPUnit\TestFixture\Repeat\DependsTest::testTwo) +Test Finished (PHPUnit\TestFixture\Repeat\DependsTest::testTwo) +Test Suite Finished (PHPUnit\TestFixture\Repeat\DependsTest, 3 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-skips-no-return-type.phpt b/tests/end-to-end/repeat/repeat-skips-no-return-type.phpt new file mode 100644 index 00000000000..8676fc50ce5 --- /dev/null +++ b/tests/end-to-end/repeat/repeat-skips-no-return-type.phpt @@ -0,0 +1,41 @@ +--TEST-- +--repeat skips test without return type declaration +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (3 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (3 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\NoReturnTypeTest, 3 tests) +Test Preparation Started (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithoutReturnType) +Test Prepared (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithoutReturnType) +Test Passed (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithoutReturnType) +Test Finished (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithoutReturnType) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\NoReturnTypeTest::testWithVoidReturn, 2 repetitions) +Test Suite Finished (PHPUnit\TestFixture\Repeat\NoReturnTypeTest, 3 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-skips-non-void-return.phpt b/tests/end-to-end/repeat/repeat-skips-non-void-return.phpt new file mode 100644 index 00000000000..33f0968191c --- /dev/null +++ b/tests/end-to-end/repeat/repeat-skips-non-void-return.phpt @@ -0,0 +1,41 @@ +--TEST-- +--repeat does not repeat test with non-void return type +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (3 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (3 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\NonVoidReturnTest, 3 tests) +Test Preparation Started (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithReturnValue) +Test Prepared (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithReturnValue) +Test Passed (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithReturnValue) +Test Finished (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithReturnValue) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\NonVoidReturnTest::testWithVoidReturn, 2 repetitions) +Test Suite Finished (PHPUnit\TestFixture\Repeat\NonVoidReturnTest, 3 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-skips-union-return-type.phpt b/tests/end-to-end/repeat/repeat-skips-union-return-type.phpt new file mode 100644 index 00000000000..ce25ac45039 --- /dev/null +++ b/tests/end-to-end/repeat/repeat-skips-union-return-type.phpt @@ -0,0 +1,41 @@ +--TEST-- +--repeat does not repeat test with union return type +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (3 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (3 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest, 3 tests) +Test Preparation Started (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithUnionReturnType) +Test Prepared (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithUnionReturnType) +Test Passed (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithUnionReturnType) +Test Finished (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithUnionReturnType) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest::testWithVoidReturn, 2 repetitions) +Test Suite Finished (PHPUnit\TestFixture\Repeat\UnionReturnTypeTest, 3 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-success.phpt b/tests/end-to-end/repeat/repeat-success.phpt new file mode 100644 index 00000000000..848bc11beea --- /dev/null +++ b/tests/end-to-end/repeat/repeat-success.phpt @@ -0,0 +1,55 @@ +--TEST-- +--repeat with all tests passing +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (6 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (6 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\SuccessTest, 6 tests) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne, 3 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 3)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 3)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 3 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 3 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 3 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 3 of 3)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne, 3 repetitions) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo, 3 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 1 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 1 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 1 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 1 of 3)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 2 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 2 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 2 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 2 of 3)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 3 of 3)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 3 of 3)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 3 of 3)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 3 of 3)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo, 3 repetitions) +Test Suite Finished (PHPUnit\TestFixture\Repeat\SuccessTest, 6 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-with-data-provider.phpt b/tests/end-to-end/repeat/repeat-with-data-provider.phpt new file mode 100644 index 00000000000..2700a3e558a --- /dev/null +++ b/tests/end-to-end/repeat/repeat-with-data-provider.phpt @@ -0,0 +1,52 @@ +--TEST-- +--repeat with data provider repeats each data set independently +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Data Provider Method Called (PHPUnit\TestFixture\Repeat\DataProviderTest::provider for test method PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider) +Data Provider Method Finished for PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider: +- PHPUnit\TestFixture\Repeat\DataProviderTest::provider +Test Suite Loaded (4 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (4 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\DataProviderTest, 4 tests) +Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider, 4 data sets) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#one, 2 repetitions) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider#two, 2 repetitions) +Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\Repeat\DataProviderTest::testWithDataProvider, 4 data sets) +Test Suite Finished (PHPUnit\TestFixture\Repeat\DataProviderTest, 4 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-with-filter.phpt b/tests/end-to-end/repeat/repeat-with-filter.phpt new file mode 100644 index 00000000000..0c0d768457d --- /dev/null +++ b/tests/end-to-end/repeat/repeat-with-filter.phpt @@ -0,0 +1,40 @@ +--TEST-- +--repeat works with --filter to select specific tests +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (4 tests) +Test Runner Started +Test Suite Sorted +Test Suite Filtered (2 tests) +Test Runner Execution Started (2 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\SuccessTest, 2 tests) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne, 2 repetitions) +Test Suite Finished (PHPUnit\TestFixture\Repeat\SuccessTest, 2 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/end-to-end/repeat/repeat-with-order-by-defects.phpt b/tests/end-to-end/repeat/repeat-with-order-by-defects.phpt new file mode 100644 index 00000000000..6367e8b0594 --- /dev/null +++ b/tests/end-to-end/repeat/repeat-with-order-by-defects.phpt @@ -0,0 +1,48 @@ +--TEST-- +--repeat works with --order-by=defects +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Event Facade Sealed +Test Suite Loaded (4 tests) +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (4 tests) +Test Suite Started (PHPUnit\TestFixture\Repeat\SuccessTest, 4 tests) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testOne, 2 repetitions) +Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo, 2 repetitions) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 1 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 1 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 1 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 1 of 2)) +Test Preparation Started (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 2 of 2)) +Test Prepared (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 2 of 2)) +Test Passed (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 2 of 2)) +Test Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo (repetition 2 of 2)) +Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\Repeat\SuccessTest::testTwo, 2 repetitions) +Test Suite Finished (PHPUnit\TestFixture\Repeat\SuccessTest, 4 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/unit/Event/Events/TestSuite/FinishedTest.php b/tests/unit/Event/Events/TestSuite/FinishedTest.php index 53366571943..1a42331bf87 100644 --- a/tests/unit/Event/Events/TestSuite/FinishedTest.php +++ b/tests/unit/Event/Events/TestSuite/FinishedTest.php @@ -10,6 +10,7 @@ namespace PHPUnit\Event\TestSuite; use PHPUnit\Event\AbstractEventTestCase; +use PHPUnit\Event\Code\TestCollection; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Small; @@ -43,4 +44,46 @@ public function testCanBeRepresentedAsString(): void $this->assertSame('Test Suite Finished (foo, 9001 tests)', $event->asString()); } + + public function testCanBeRepresentedAsStringForTestSuiteForTestMethodWithDataProvider(): void + { + $event = new Finished( + $this->telemetryInfo(), + new TestSuiteForTestMethodWithDataProvider( + 'PHPUnit\TestFixture\ExampleTest::testSomething', + 2, + TestCollection::fromArray([]), + 'PHPUnit\TestFixture\ExampleTest', + 'testSomething', + 'ExampleTest.php', + 10, + ), + ); + + $this->assertSame( + 'Test Suite for Test Method with Data Provider Finished (PHPUnit\TestFixture\ExampleTest::testSomething, 2 data sets)', + $event->asString(), + ); + } + + public function testCanBeRepresentedAsStringForTestSuiteForRepeatedTestMethod(): void + { + $event = new Finished( + $this->telemetryInfo(), + new TestSuiteForRepeatedTestMethod( + 'PHPUnit\TestFixture\ExampleTest::testSomething', + 3, + TestCollection::fromArray([]), + 'PHPUnit\TestFixture\ExampleTest', + 'testSomething', + 'ExampleTest.php', + 10, + ), + ); + + $this->assertSame( + 'Test Suite for Repeated Test Method Finished (PHPUnit\TestFixture\ExampleTest::testSomething, 3 repetitions)', + $event->asString(), + ); + } } diff --git a/tests/unit/Event/Events/TestSuite/StartedTest.php b/tests/unit/Event/Events/TestSuite/StartedTest.php index afb771f989f..c5b368b602c 100644 --- a/tests/unit/Event/Events/TestSuite/StartedTest.php +++ b/tests/unit/Event/Events/TestSuite/StartedTest.php @@ -10,6 +10,7 @@ namespace PHPUnit\Event\TestSuite; use PHPUnit\Event\AbstractEventTestCase; +use PHPUnit\Event\Code\TestCollection; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Small; @@ -40,4 +41,46 @@ public function testCanBeRepresentedAsString(): void $this->assertSame('Test Suite Started (foo, 9001 tests)', $event->asString()); } + + public function testCanBeRepresentedAsStringForTestSuiteForTestMethodWithDataProvider(): void + { + $event = new Started( + $this->telemetryInfo(), + new TestSuiteForTestMethodWithDataProvider( + 'PHPUnit\TestFixture\ExampleTest::testSomething', + 2, + TestCollection::fromArray([]), + 'PHPUnit\TestFixture\ExampleTest', + 'testSomething', + 'ExampleTest.php', + 10, + ), + ); + + $this->assertSame( + 'Test Suite for Test Method with Data Provider Started (PHPUnit\TestFixture\ExampleTest::testSomething, 2 data sets)', + $event->asString(), + ); + } + + public function testCanBeRepresentedAsStringForTestSuiteForRepeatedTestMethod(): void + { + $event = new Started( + $this->telemetryInfo(), + new TestSuiteForRepeatedTestMethod( + 'PHPUnit\TestFixture\ExampleTest::testSomething', + 3, + TestCollection::fromArray([]), + 'PHPUnit\TestFixture\ExampleTest', + 'testSomething', + 'ExampleTest.php', + 10, + ), + ); + + $this->assertSame( + 'Test Suite for Repeated Test Method Started (PHPUnit\TestFixture\ExampleTest::testSomething, 3 repetitions)', + $event->asString(), + ); + } } diff --git a/tests/unit/Event/Value/Test/TestMethodTest.php b/tests/unit/Event/Value/Test/TestMethodTest.php index 0b035299a0d..a546beeea5a 100644 --- a/tests/unit/Event/Value/Test/TestMethodTest.php +++ b/tests/unit/Event/Value/Test/TestMethodTest.php @@ -56,6 +56,73 @@ public function testConstructorSetsValues(): void $this->assertSame($testData, $test->testData()); $this->assertTrue($test->isTestMethod()); $this->assertFalse($test->isPhpt()); + $this->assertSame(1, $test->repetition()); + $this->assertSame(1, $test->totalRepetitions()); + $this->assertFalse($test->isRepeated()); + } + + public function testRepetitionValues(): void + { + $test = new TestMethod( + 'FooTest', + 'testBar', + 'FooTest.php', + 1, + TestDoxBuilder::fromClassNameAndMethodName('Foo', 'bar'), + MetadataCollection::fromArray([]), + TestDataCollection::fromArray([]), + 2, + 3, + ); + + $this->assertSame(2, $test->repetition()); + $this->assertSame(3, $test->totalRepetitions()); + $this->assertTrue($test->isRepeated()); + } + + public function testNameIncludesRepetitionWhenRepeated(): void + { + $test = new TestMethod( + 'FooTest', + 'testBar', + 'FooTest.php', + 1, + TestDoxBuilder::fromClassNameAndMethodName('Foo', 'bar'), + MetadataCollection::fromArray([]), + TestDataCollection::fromArray([]), + 2, + 3, + ); + + $this->assertSame('testBar (repetition 2 of 3)', $test->name()); + $this->assertSame('FooTest::testBar (repetition 2 of 3)', $test->nameWithClass()); + $this->assertSame('FooTest::testBar (repetition 2 of 3)', $test->id()); + } + + public function testNameIncludesDataProviderAndRepetition(): void + { + $test = new TestMethod( + 'FooTest', + 'testBar', + 'FooTest.php', + 1, + TestDoxBuilder::fromClassNameAndMethodName('Foo', 'bar'), + MetadataCollection::fromArray([]), + TestDataCollection::fromArray( + [ + DataFromDataProvider::from( + 0, + 'data', + 'data as string for result output', + ), + ], + ), + 2, + 3, + ); + + $this->assertSame('testBar with data set #0 (repetition 2 of 3)', $test->name()); + $this->assertSame('FooTest::testBar#0 (repetition 2 of 3)', $test->id()); } public function testNameReturnsNameWhenTestDoesNotHaveDataFromDataProvider(): void diff --git a/tests/unit/Event/Value/TestSuite/TestSuiteTest.php b/tests/unit/Event/Value/TestSuite/TestSuiteTest.php index 25ddc3b4532..12aa1e7ffc3 100644 --- a/tests/unit/Event/Value/TestSuite/TestSuiteTest.php +++ b/tests/unit/Event/Value/TestSuite/TestSuiteTest.php @@ -59,6 +59,33 @@ public function testCanBeTestSuiteForTestMethodWithDataProvider(): void $this->assertFalse($testSuite->isForTestClass()); $this->assertTrue($testSuite->isForTestMethodWithDataProvider()); + $this->assertFalse($testSuite->isForRepeatedTestMethod()); + $this->assertFalse($testSuite->isWithName()); + + $this->assertSame($name, $testSuite->name()); + $this->assertSame($className, $testSuite->className()); + $this->assertSame($methodName, $testSuite->methodName()); + $this->assertSame($size, $testSuite->count()); + $this->assertSame($tests, $testSuite->tests()); + $this->assertSame($file, $testSuite->file()); + $this->assertSame($line, $testSuite->line()); + } + + public function testCanBeTestSuiteForRepeatedTestMethod(): void + { + $name = 'ExampleTest::testOne'; + $className = 'ExampleTest'; + $methodName = 'testOne'; + $size = 0; + $tests = TestCollection::fromArray([]); + $file = 'ExampleTest.php'; + $line = 1; + + $testSuite = new TestSuiteForRepeatedTestMethod($name, $size, $tests, $className, $methodName, $file, $line); + + $this->assertFalse($testSuite->isForTestClass()); + $this->assertFalse($testSuite->isForTestMethodWithDataProvider()); + $this->assertTrue($testSuite->isForRepeatedTestMethod()); $this->assertFalse($testSuite->isWithName()); $this->assertSame($name, $testSuite->name()); diff --git a/tests/unit/Framework/RepeatTestSuiteTest.php b/tests/unit/Framework/RepeatTestSuiteTest.php new file mode 100644 index 00000000000..54ab87c002f --- /dev/null +++ b/tests/unit/Framework/RepeatTestSuiteTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Small; +use PHPUnit\TestFixture\Success; + +#[CoversClass(RepeatTestSuite::class)] +#[Small] +final class RepeatTestSuiteTest extends TestCase +{ + public function testCountReturnsNumberOfRepetitions(): void + { + $tests = [ + new Success('testOne'), + new Success('testOne'), + new Success('testOne'), + ]; + + $suite = RepeatTestSuite::fromTests('PHPUnit\TestFixture\Success::testOne', $tests, 1); + + $this->assertCount(3, $suite); + } + + public function testNameReturnsValueProvidedToFactory(): void + { + $suite = RepeatTestSuite::fromTests( + 'PHPUnit\TestFixture\Success::testOne', + [new Success('testOne')], + 1, + ); + + $this->assertSame('PHPUnit\TestFixture\Success::testOne', $suite->name()); + } + + public function testSortIdDelegatesToFirstChild(): void + { + $test = new Success('testOne'); + + $suite = RepeatTestSuite::fromTests( + 'PHPUnit\TestFixture\Success::testOne', + [$test], + 1, + ); + + $this->assertSame($test->sortId(), $suite->sortId()); + } +} diff --git a/tests/unit/Metadata/MetadataCollectionTest.php b/tests/unit/Metadata/MetadataCollectionTest.php index 540cbeb33a9..9376e951e55 100644 --- a/tests/unit/Metadata/MetadataCollectionTest.php +++ b/tests/unit/Metadata/MetadataCollectionTest.php @@ -41,6 +41,7 @@ #[UsesClass(PostCondition::class)] #[UsesClass(PreCondition::class)] #[UsesClass(PreserveGlobalState::class)] +#[UsesClass(Repeat::class)] #[UsesClass(RequiresFunction::class)] #[UsesClass(RequiresMethod::class)] #[UsesClass(RequiresOperatingSystem::class)] @@ -571,6 +572,14 @@ public function test_Can_be_filtered_for_UsesMethod(): void $this->assertTrue($collection->asArray()[0]->isUsesMethod()); } + public function test_Can_be_filtered_for_Repeat(): void + { + $collection = $this->collectionWithOneOfEach()->isRepeat(); + + $this->assertCount(1, $collection); + $this->assertTrue($collection->asArray()[0]->isRepeat()); + } + public function test_Can_be_filtered_for_WithoutErrorHandler(): void { $collection = $this->collectionWithOneOfEach()->isWithoutErrorHandler(); @@ -650,6 +659,7 @@ private function collectionWithOneOfEach(): MetadataCollection Metadata::usesTrait(''), Metadata::usesFunction(''), Metadata::usesMethod('', ''), + Metadata::repeat(3, 1), Metadata::withEnvironmentVariableOnClass('foo', 'bar'), Metadata::withoutErrorHandler(), ], diff --git a/tests/unit/Metadata/MetadataTest.php b/tests/unit/Metadata/MetadataTest.php index b39471dc2df..42d1c8aee0e 100644 --- a/tests/unit/Metadata/MetadataTest.php +++ b/tests/unit/Metadata/MetadataTest.php @@ -57,6 +57,7 @@ public function testCanBeAfter(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -124,6 +125,7 @@ public function testCanBeAfterClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -189,6 +191,7 @@ public function testCanBeAllowMockObjectsWithoutExpectations(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -253,6 +256,7 @@ public function testCanBeBackupGlobalsOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -318,6 +322,7 @@ public function testCanBeBackupGlobalsOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -383,6 +388,7 @@ public function testCanBeBackupStaticPropertiesOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -448,6 +454,7 @@ public function testCanBeBackupStaticPropertiesOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -515,6 +522,7 @@ public function testCanBeBeforeClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -581,6 +589,7 @@ public function testCanBeBefore(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -646,6 +655,7 @@ public function testCanBeCoversClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -714,6 +724,7 @@ public function testCanBeCoversNamespace(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -780,6 +791,7 @@ public function testCanBeCoversClassesThatExtendClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -846,6 +858,7 @@ public function testCanBeCoversClassesThatImplementInterface(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -912,6 +925,7 @@ public function testCanBeCoversFunction(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -978,6 +992,7 @@ public function testCanBeCoversMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1045,6 +1060,7 @@ public function testCanBeCoversNothingOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1109,6 +1125,7 @@ public function testCanBeCoversNothingOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1173,6 +1190,7 @@ public function testCanBeCoversTrait(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1239,6 +1257,7 @@ public function testCanBeDataProvider(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1311,6 +1330,7 @@ public function testCanBeDataProviderClosure(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1378,6 +1398,7 @@ public function testCanBeDependsOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1446,6 +1467,7 @@ public function testCanBeDependsOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1515,6 +1537,7 @@ public function testCanBeDisableReturnValueGenerationForTestDoubles(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1579,6 +1602,7 @@ public function testCanBeDoesNotPerformAssertionsOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1643,6 +1667,7 @@ public function testCanBeDoesNotPerformAssertionsOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1707,6 +1732,7 @@ public function testCanBeExcludeGlobalVariableFromBackupOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1772,6 +1798,7 @@ public function testCanBeExcludeGlobalVariableFromBackupOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1837,6 +1864,7 @@ public function testCanBeExcludeStaticPropertyFromBackupOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1904,6 +1932,7 @@ public function testCanBeExcludeStaticPropertyFromBackupOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -1971,6 +2000,7 @@ public function testCanBeGroupOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2039,6 +2069,7 @@ public function testCanBeIgnoreDeprecationsOnClass(): void $this->assertTrue($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2104,6 +2135,7 @@ public function testCanBeIgnoreDeprecationsOnMethod(): void $this->assertTrue($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2168,6 +2200,7 @@ public function testCanBeIgnorePhpunitDeprecationsOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertTrue($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2232,6 +2265,7 @@ public function testCanBeIgnorePhpunitDeprecationsOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertTrue($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2363,6 +2397,7 @@ public function testCanBeGroupOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2429,6 +2464,7 @@ public function testCanBeRunTestsInSeparateProcesses(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertTrue($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2557,6 +2593,7 @@ public function testCanBeTest(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertTrue($metadata->isTest()); @@ -2623,6 +2660,7 @@ public function testCanBePreCondition(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2690,6 +2728,7 @@ public function testCanBePostCondition(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2751,6 +2790,7 @@ public function testCanBePreserveGlobalStateOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2813,6 +2853,7 @@ public function testCanBePreserveGlobalStateOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2879,6 +2920,7 @@ public function testCanBeRequiresMethodOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -2946,6 +2988,7 @@ public function testCanBeRequiresMethodOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3013,6 +3056,7 @@ public function testCanBeRequiresFunctionOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3079,6 +3123,7 @@ public function testCanBeRequiresFunctionOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3145,6 +3190,7 @@ public function testCanBeRequiresOperatingSystemOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3211,6 +3257,7 @@ public function testCanBeRequiresOperatingSystemOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3277,6 +3324,7 @@ public function testCanBeRequiresOperatingSystemFamilyOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3343,6 +3391,7 @@ public function testCanBeRequiresOperatingSystemFamilyOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3414,6 +3463,7 @@ public function testCanBeRequiresPhpOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3485,6 +3535,7 @@ public function testCanBeRequiresPhpOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3551,6 +3602,7 @@ public function testCanBeRequiresPhpExtensionOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3627,6 +3679,7 @@ public function testCanBeRequiresPhpExtensionWithVersionOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3695,6 +3748,7 @@ public function testCanBeRequiresPhpExtensionOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3771,6 +3825,7 @@ public function testCanBeRequiresPhpExtensionWithVersionOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3844,6 +3899,7 @@ public function testCanBeRequiresPhpunitOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3910,6 +3966,7 @@ public function testCanBeRequiresPhpunitExtensionOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -3981,6 +4038,7 @@ public function testCanBeRequiresPhpunitOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4047,6 +4105,7 @@ public function testCanBeRequiresPhpunitExtensionOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4113,6 +4172,7 @@ public function testCanBeRequiresEnvironmentVariableOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4180,6 +4240,7 @@ public function testCanBeRequiresEnvironmentVariableOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4247,6 +4308,7 @@ public function testCanBeWithEnvironmentVariableOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4314,6 +4376,7 @@ public function testCanBeWithEnvironmentVariableOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4381,6 +4444,7 @@ public function testCanBeRequiresSettingOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4448,6 +4512,7 @@ public function testCanBeRequiresSettingOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4515,6 +4580,7 @@ public function testCanBeTestDoxOnClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4581,6 +4647,7 @@ public function testCanBeTestDoxOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4647,6 +4714,7 @@ public function testCanBeTestDoxFormatterOnMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4714,6 +4782,7 @@ public function testCanBeTestWith(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4783,6 +4852,7 @@ public function testCanBeUsesNamespace(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4849,6 +4919,7 @@ public function testCanBeUsesClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4915,6 +4986,7 @@ public function testCanBeUsesClassesThatExtendClass(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -4981,6 +5053,7 @@ public function testCanBeUsesClassesThatImplementInterface(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -5047,6 +5120,7 @@ public function testCanBeUsesFunction(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -5112,6 +5186,7 @@ public function testCanBeUsesMethod(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -5179,6 +5254,7 @@ public function testCanBeUsesTrait(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -5245,6 +5321,7 @@ public function testCanBeWithoutErrorHandler(): void $this->assertFalse($metadata->isIgnoreDeprecations()); $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertFalse($metadata->isRepeat()); $this->assertFalse($metadata->isRunInSeparateProcess()); $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); $this->assertFalse($metadata->isTest()); @@ -5277,4 +5354,72 @@ public function testCanBeWithoutErrorHandler(): void $this->assertTrue($metadata->isMethodLevel()); $this->assertFalse($metadata->isClassLevel()); } + + public function testCanBeRepeat(): void + { + $metadata = Metadata::repeat(3, 2); + + $this->assertFalse($metadata->isAfter()); + $this->assertFalse($metadata->isAfterClass()); + $this->assertFalse($metadata->isAllowMockObjectsWithoutExpectations()); + $this->assertFalse($metadata->isBackupGlobals()); + $this->assertFalse($metadata->isBackupStaticProperties()); + $this->assertFalse($metadata->isBeforeClass()); + $this->assertFalse($metadata->isBefore()); + $this->assertFalse($metadata->isCoversNamespace()); + $this->assertFalse($metadata->isCoversClass()); + $this->assertFalse($metadata->isCoversClassesThatExtendClass()); + $this->assertFalse($metadata->isCoversClassesThatImplementInterface()); + $this->assertFalse($metadata->isCoversFunction()); + $this->assertFalse($metadata->isCoversMethod()); + $this->assertFalse($metadata->isCoversNothing()); + $this->assertFalse($metadata->isCoversTrait()); + $this->assertFalse($metadata->isDataProvider()); + $this->assertFalse($metadata->isDataProviderClosure()); + $this->assertFalse($metadata->isDependsOnClass()); + $this->assertFalse($metadata->isDependsOnMethod()); + $this->assertFalse($metadata->isDisableReturnValueGenerationForTestDoubles()); + $this->assertFalse($metadata->isDoesNotPerformAssertions()); + $this->assertFalse($metadata->isExcludeGlobalVariableFromBackup()); + $this->assertFalse($metadata->isExcludeStaticPropertyFromBackup()); + $this->assertFalse($metadata->isGroup()); + $this->assertFalse($metadata->isIgnoreDeprecations()); + $this->assertFalse($metadata->isIgnorePhpunitDeprecations()); + $this->assertFalse($metadata->isIgnorePHPUnitWarnings()); + $this->assertTrue($metadata->isRepeat()); + $this->assertFalse($metadata->isRunInSeparateProcess()); + $this->assertFalse($metadata->isRunTestsInSeparateProcesses()); + $this->assertFalse($metadata->isTest()); + $this->assertFalse($metadata->isPreCondition()); + $this->assertFalse($metadata->isPostCondition()); + $this->assertFalse($metadata->isPreserveGlobalState()); + $this->assertFalse($metadata->isRequiresMethod()); + $this->assertFalse($metadata->isRequiresFunction()); + $this->assertFalse($metadata->isRequiresOperatingSystem()); + $this->assertFalse($metadata->isRequiresOperatingSystemFamily()); + $this->assertFalse($metadata->isRequiresPhp()); + $this->assertFalse($metadata->isRequiresPhpExtension()); + $this->assertFalse($metadata->isRequiresPhpunit()); + $this->assertFalse($metadata->isRequiresPhpunitExtension()); + $this->assertFalse($metadata->isRequiresEnvironmentVariable()); + $this->assertFalse($metadata->isWithEnvironmentVariable()); + $this->assertFalse($metadata->isRequiresSetting()); + $this->assertFalse($metadata->isTestDox()); + $this->assertFalse($metadata->isTestDoxFormatter()); + $this->assertFalse($metadata->isTestWith()); + $this->assertFalse($metadata->isUsesNamespace()); + $this->assertFalse($metadata->isUsesClass()); + $this->assertFalse($metadata->isUsesClassesThatExtendClass()); + $this->assertFalse($metadata->isUsesClassesThatImplementInterface()); + $this->assertFalse($metadata->isUsesFunction()); + $this->assertFalse($metadata->isUsesMethod()); + $this->assertFalse($metadata->isUsesTrait()); + $this->assertFalse($metadata->isWithoutErrorHandler()); + + $this->assertSame(3, $metadata->times()); + $this->assertSame(2, $metadata->failureThreshold()); + + $this->assertTrue($metadata->isMethodLevel()); + $this->assertFalse($metadata->isClassLevel()); + } } diff --git a/tests/unit/Metadata/Parser/AttributeParserTestCase.php b/tests/unit/Metadata/Parser/AttributeParserTestCase.php index 236b287e065..09e7875ad8b 100644 --- a/tests/unit/Metadata/Parser/AttributeParserTestCase.php +++ b/tests/unit/Metadata/Parser/AttributeParserTestCase.php @@ -15,6 +15,7 @@ use PHPUnit\Metadata\DependsOnClass; use PHPUnit\Metadata\DependsOnMethod; use PHPUnit\Metadata\InvalidAttributeException; +use PHPUnit\Metadata\Repeat; use PHPUnit\Metadata\RequiresEnvironmentVariable; use PHPUnit\Metadata\RequiresPhp; use PHPUnit\Metadata\RequiresPhpExtension; @@ -52,6 +53,7 @@ use PHPUnit\TestFixture\Metadata\Attribute\PhpunitAttributeThatDoesNotExistTest; use PHPUnit\TestFixture\Metadata\Attribute\PreserveGlobalStateTest; use PHPUnit\TestFixture\Metadata\Attribute\ProcessIsolationTest; +use PHPUnit\TestFixture\Metadata\Attribute\RepeatTest; use PHPUnit\TestFixture\Metadata\Attribute\RequiresEnvironmentVariableTest; use PHPUnit\TestFixture\Metadata\Attribute\RequiresFunctionTest; use PHPUnit\TestFixture\Metadata\Attribute\RequiresMethodTest; @@ -1213,6 +1215,22 @@ public function test_parses_Ticket_attribute_on_method(): void $this->assertSame('another-ticket', $metadata->asArray()[1]->groupName()); } + #[TestDox('Parses #[Repeat] attribute on method')] + public function test_parses_Repeat_attribute_on_method(): void + { + $metadata = $this->parser()->forMethod(RepeatTest::class, 'testOne')->isRepeat(); + + $this->assertCount(1, $metadata); + $this->assertTrue($metadata->asArray()[0]->isRepeat()); + + $repeat = $metadata->asArray()[0]; + + assert($repeat instanceof Repeat); + + $this->assertSame(5, $repeat->times()); + $this->assertSame(2, $repeat->failureThreshold()); + } + #[TestDox('Parses #[WithoutErrorHandler] attribute on method')] public function test_parses_WithoutErrorHandler_attribute_on_method(): void { diff --git a/tests/unit/TextUI/Configuration/Cli/BuilderTest.php b/tests/unit/TextUI/Configuration/Cli/BuilderTest.php index cb41c882f18..ea912761166 100644 --- a/tests/unit/TextUI/Configuration/Cli/BuilderTest.php +++ b/tests/unit/TextUI/Configuration/Cli/BuilderTest.php @@ -2952,6 +2952,26 @@ public function testExtensionMayNotBeConfigured(): void $configuration->extensions(); } + #[TestDox('--repeat')] + public function testRepeat(): void + { + $configuration = (new Builder)->fromParameters(['--repeat', '3']); + + $this->assertTrue($configuration->hasRepeat()); + $this->assertSame(3, $configuration->repeat()); + } + + public function testRepeatMayNotBeConfigured(): void + { + $configuration = (new Builder)->fromParameters([]); + + $this->assertFalse($configuration->hasRepeat()); + + $this->expectException(Exception::class); + + $configuration->repeat(); + } + public function testInvalidOption(): void { $this->expectException(Exception::class);