1212use function assert ;
1313use function base64_encode ;
1414use function bin2hex ;
15+ use function count ;
1516use function defined ;
1617use function file_get_contents ;
1718use function get_include_path ;
2627use function unlink ;
2728use function var_export ;
2829use PHPUnit \Event \Facade as EventFacade ;
30+ use PHPUnit \Framework \RepeatTestSuite ;
31+ use PHPUnit \Framework \RetryTestSuite ;
32+ use PHPUnit \Framework \TestCase ;
2933use PHPUnit \Runner \CodeCoverage ;
3034use PHPUnit \TextUI \Configuration \Registry as ConfigurationRegistry ;
3135use PHPUnit \TextUI \Configuration \SourceMapper ;
@@ -263,31 +267,43 @@ private function testClassCommand(TestClassWorkUnit $unit, array $offset, string
263267 $ tests = [];
264268
265269 foreach ($ unit ->tests () as $ test ) {
266- try {
267- $ data = base64_encode (serialize ($ test ->providedData ()));
268- $ dependencyInput = base64_encode (serialize ($ test ->dependencyInput ()));
269- } catch (Throwable $ t ) {
270- @unlink ($ resultFile );
271-
272- throw new WorkerException (
273- sprintf (
274- 'The tests of class %s cannot be run in parallel because their data cannot be serialized: %s ' ,
275- $ unit ->className (),
276- $ t ->getMessage (),
277- ),
278- );
270+ if ($ test instanceof RetryTestSuite) {
271+ $ aggregated = $ test ->tests ();
272+
273+ assert (count ($ aggregated ) === 1 && $ aggregated [0 ] instanceof TestCase);
274+
275+ $ tests [] = [
276+ 'type ' => 'retry ' ,
277+ 'name ' => $ test ->name (),
278+ 'maxAttempts ' => $ test ->maxAttempts (),
279+ 'test ' => $ this ->testDescriptor ($ aggregated [0 ], $ unit ->className (), $ resultFile ),
280+ ];
281+
282+ continue ;
283+ }
284+
285+ if ($ test instanceof RepeatTestSuite) {
286+ $ repetitions = [];
287+
288+ foreach ($ test ->tests () as $ repetition ) {
289+ assert ($ repetition instanceof TestCase);
290+
291+ $ repetitions [] = $ this ->testDescriptor ($ repetition , $ unit ->className (), $ resultFile );
292+ }
293+
294+ $ tests [] = [
295+ 'type ' => 'repeat ' ,
296+ 'name ' => $ test ->name (),
297+ 'failureThreshold ' => $ test ->failureThreshold (),
298+ 'tests ' => $ repetitions ,
299+ ];
300+
301+ continue ;
279302 }
280303
281- $ tests [] = [
282- 'methodName ' => $ test ->name (),
283- 'data ' => $ data ,
284- 'dataName ' => $ test ->dataName (),
285- 'dependencyInput ' => $ dependencyInput ,
286- 'repetition ' => $ test ->repetition (),
287- 'totalRepetitions ' => $ test ->totalRepetitions (),
288- 'attempt ' => $ test ->attempt (),
289- 'maxAttempts ' => $ test ->maxAttempts (),
290- ];
304+ assert ($ test instanceof TestCase);
305+
306+ $ tests [] = $ this ->testDescriptor ($ test , $ unit ->className (), $ resultFile );
291307 }
292308
293309 return [
@@ -303,6 +319,47 @@ private function testClassCommand(TestClassWorkUnit $unit, array $offset, string
303319 ];
304320 }
305321
322+ /**
323+ * The transportable description of a single test case, from which the
324+ * worker reconstructs it.
325+ *
326+ * @param class-string $className
327+ * @param non-empty-string $resultFile
328+ *
329+ * @throws WorkerException
330+ *
331+ * @return array<string, mixed>
332+ */
333+ private function testDescriptor (TestCase $ test , string $ className , string $ resultFile ): array
334+ {
335+ try {
336+ $ data = base64_encode (serialize ($ test ->providedData ()));
337+ $ dependencyInput = base64_encode (serialize ($ test ->dependencyInput ()));
338+ } catch (Throwable $ t ) {
339+ @unlink ($ resultFile );
340+
341+ throw new WorkerException (
342+ sprintf (
343+ 'The tests of class %s cannot be run in parallel because their data cannot be serialized: %s ' ,
344+ $ className ,
345+ $ t ->getMessage (),
346+ ),
347+ );
348+ }
349+
350+ return [
351+ 'type ' => 'test ' ,
352+ 'methodName ' => $ test ->name (),
353+ 'data ' => $ data ,
354+ 'dataName ' => $ test ->dataName (),
355+ 'dependencyInput ' => $ dependencyInput ,
356+ 'repetition ' => $ test ->repetition (),
357+ 'totalRepetitions ' => $ test ->totalRepetitions (),
358+ 'attempt ' => $ test ->attempt (),
359+ 'maxAttempts ' => $ test ->maxAttempts (),
360+ ];
361+ }
362+
306363 /**
307364 * Harvest the result of the unit the worker has just reported as finished.
308365 */
0 commit comments