Repository navigation
[SUREFIRE-2239, SUREFIRE-2241, SUREFIRE-2260, SUREFIRE-2274, SUREFIRE-2300] Preserve JUnit Platform test identity across reruns - #3418
Merged
olamy merged 5 commits intoAug 14, 2026
Conversation
wilx
marked this pull request as ready for review
August 8, 2026 21:20
wilx
marked this pull request as draft
August 8, 2026 21:32
wilx
force-pushed
the
issue-2686-junit-platform-rerun-identity
branch
from
August 8, 2026 22:08
171b2c4 to
52fa065
Compare
wilx
marked this pull request as ready for review
August 8, 2026 22:21
This was referenced Aug 8, 2026
wilx
force-pushed
the
issue-2686-junit-platform-rerun-identity
branch
from
August 8, 2026 23:14
2642374 to
3f1d74b
Compare
Contributor
Author
|
I have pushed 2d29ea4 to try to avoid some sort of threading issue in possibly TestNG. I have seen the failure in |
Member
|
The PR has some conflicts |
Use the JUnit Platform unique ID as the internal run identity while retaining human-readable report names. Aggregate XML and global results by that identity so equally named tests and scenarios remain distinct, and keep skipped rerun entries valid in flaky XML output. Add regressions for the JUnitParams and Cucumber reproducers. Fixes apache#2686 Fixes apache#2670
Recover the fail-first/pass-second TestNG reproducer and exercise it through both Surefire and Failsafe using the JUnit Platform provider. Assert that each final report records one flake. Fixes apache#2626
Adapt the linked reproducer to verify that Failsafe persists rerun flakes in its summary and enforces failOnFlakeCount during verify. Fixes apache#2656
Use the JUnit Platform TestPlan to report every discovered test under a class aborted by a BeforeAll assumption as skipped while preserving completed results for later container aborts. Fixes apache#2602
Update the method-pattern fixture to TestNG 7.5.1, the latest version supporting Java 8, to avoid a suspected class-lifecycle race fixed after TestNG 6.14.3. Fixes apache#2686
wilx
force-pushed
the
issue-2686-junit-platform-rerun-identity
branch
from
August 11, 2026 05:58
2d29ea4 to
51d6fab
Compare
Contributor
Author
Rebased. |
There was a problem hiding this comment.
Pull request overview
Preserves JUnit Platform test identity across reruns, improving flake aggregation, runner-backed reruns, and aborted-class reporting.
Changes:
- Uses unique IDs to distinguish identically named tests and associate rerun output.
- Adds class-based rediscovery and descendant skip reporting.
- Adds regression coverage for JUnitParams, Cucumber, TestNG, Failsafe, and
@BeforeAllassumptions.
Reviewed changes
Copilot reviewed 34 out of 34 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/RunListenerAdapterTest.java |
Tests identity, filtering, naming, and aborted classes. |
surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java |
Tests class-backed rerun discovery. |
surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java |
Propagates identity and filters rerun events. |
surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java |
Builds filtered rerun discovery requests. |
surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/ClassMethodIndexerTest.java |
Tests cached-ID restoration. |
surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/ClassMethodIndexer.java |
Restores cached IDs to thread-local state. |
surefire-its/src/test/resources/testng-multiple-method-patterns/pom.xml |
Updates the TestNG fixture version. |
surefire-its/src/test/resources/surefire-2300-before-all-assumption/src/test/java/example/TestAssume.java |
Adds aborted-class fixture tests. |
surefire-its/src/test/resources/surefire-2300-before-all-assumption/pom.xml |
Configures the assumption fixture. |
surefire-its/src/test/resources/surefire-2274-failsafe-flake-count/src/test/java/example/ReproducerIT.java |
Adds fail-twice Failsafe tests. |
surefire-its/src/test/resources/surefire-2274-failsafe-flake-count/pom.xml |
Configures Failsafe flake enforcement. |
surefire-its/src/test/resources/surefire-2260-non-unique-scenarios/src/test/resources/io/cucumber/skeleton/reproducer.feature |
Adds identically named scenarios. |
surefire-its/src/test/resources/surefire-2260-non-unique-scenarios/src/test/java/io/cucumber/skeleton/StepDefinitions.java |
Implements scenario outcomes. |
surefire-its/src/test/resources/surefire-2260-non-unique-scenarios/src/test/java/io/cucumber/skeleton/CucumberReproducerTest.java |
Defines the Cucumber suite. |
surefire-its/src/test/resources/surefire-2260-non-unique-scenarios/pom.xml |
Configures the Cucumber fixture. |
surefire-its/src/test/resources/surefire-2241-junitparams-rerun/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java |
Adds a following-test regression case. |
surefire-its/src/test/resources/surefire-2241-junitparams-rerun/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java |
Reproduces JUnitParams reruns. |
surefire-its/src/test/resources/surefire-2241-junitparams-rerun/pom.xml |
Configures JUnitParams and Vintage. |
surefire-its/src/test/resources/surefire-2239-testng-rerun/src/test/java/example/FlakyTest.java |
Adds a flaky Surefire TestNG test. |
surefire-its/src/test/resources/surefire-2239-testng-rerun/src/test/java/example/FlakyIT.java |
Adds a flaky Failsafe TestNG test. |
surefire-its/src/test/resources/surefire-2239-testng-rerun/pom.xml |
Configures both TestNG plugin paths. |
surefire-its/src/test/java/org/apache/maven/surefire/its/Surefire2300BeforeAllAssumptionIT.java |
Verifies descendant skip reporting. |
surefire-its/src/test/java/org/apache/maven/surefire/its/Surefire2274FailsafeFlakeCountIT.java |
Verifies summary flakes and failure. |
surefire-its/src/test/java/org/apache/maven/surefire/its/Surefire2260NonUniqueScenariosIT.java |
Verifies distinct Cucumber outcomes. |
surefire-its/src/test/java/org/apache/maven/surefire/its/Surefire2241JUnitParamsRerunIT.java |
Verifies JUnitParams reports and flakes. |
surefire-its/src/test/java/org/apache/maven/surefire/its/Surefire2239TestNgRerunIT.java |
Verifies TestNG reruns end to end. |
surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1152RerunFailingTestsInSuiteIT.java |
Updates distinct-test expectations. |
maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java |
Tests XML identity and skipped reruns. |
maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactoryTest.java |
Tests global identity aggregation. |
maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/TestSetRunListener.java |
Propagates test-run IDs into statistics. |
maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/TestMethodStats.java |
Stores identity in method statistics. |
maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/TestMethodKey.java |
Defines rerun aggregation keys. |
maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java |
Aggregates XML by test identity. |
maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java |
Aggregates global results by identity. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+337
to
+341
| if (classSource.isPresent()) { | ||
| classNames.add(classSource.get().getClassName()); | ||
| } else { | ||
| builder.selectors(selectUniqueId(identifier.getUniqueId())); | ||
| } |
Comment on lines
+348
to
+349
| boolean isFailureOrRelatedContainer = failureIds.stream() | ||
| .anyMatch(failureId -> candidateId.hasPrefix(failureId) || failureId.hasPrefix(candidateId)); |
Comment on lines
+63
to
+64
| return Objects.equals(testClassMethodName, that.testClassMethodName) | ||
| && Objects.equals(testRunId, that.testRunId); |
Comment on lines
+705
to
+707
| UniqueId candidateId = UniqueId.parse(testIdentifier.getUniqueId()); | ||
| return rerunTestIds.stream() | ||
| .anyMatch(failureId -> candidateId.hasPrefix(failureId) || failureId.hasPrefix(candidateId)); |
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> |
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> |
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> |
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> |
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> |
1 task done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Following this checklist to help us incorporate your
contribution quickly and easily:
mvn clean installto make sure basic checks pass. A more thorough check willbe performed on your pull request automatically.
mvn -Prun-its clean install).If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.
To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.
I hereby declare this contribution to be licenced under the Apache License Version 2.0, January 2004
In any other case, please file an Apache Individual Contributor License Agreement.
Summary
Fixes #2686.
Fixes #2670.
Fixes #2626.
Fixes #2656.
Fixes #2602.
JUnit Platform tests were aggregated by their human-readable class and method names. Engines can legitimately report multiple logical tests with the same names, and JUnitParams on the Vintage engine reports actual tests with a
ClassSourcebut no method source. During reruns this collapsed skipped, failing, and successful executions into one apparent flake, could generate an empty XML element name, and could hide real failures.This change:
ClassSource-backed tests a readable test name;ClassSource-backed failures by class while filtering and reporting only the failed unique-ID branches, allowing runner-backed Vintage tests such as JUnitParams to rerun without parsing engine-specific unique-ID segments;failsafe-summary.xmland are enforced byverify; and@BeforeAllassumption as skipped, while preserving completed test results when a class aborts later in its lifecycle.An existing integration fixture containing two distinct tests with the same method name now correctly expects both tests in its report.
User impact
Identically named tests and scenarios remain distinct. The JUnitParams reproducer fails both parameterized cases on their first invocation, reruns those two cases successfully, records two flakes in valid XML, and continues to the following test class. The Cucumber reproducer reports three scenarios as one skipped, one failed, and one passed test. TestNG tests are also verified to rerun through the JUnit Platform provider in both Surefire and Failsafe, with one flake recorded by each plugin. Failsafe is additionally protected end to end against losing the flake count between
integration-testandverify: two fail-twice/pass-third tests produce<flakes>2</flakes>, andfailOnFlakeCount=1fails the build duringverify. A two-test class aborted by a@BeforeAllassumption now reports two tests and two skips, including both XML test cases and the original assumption cause, instead of reporting zero tests and zero skips.Tests
mvn clean installnice -n 10 env JAVA_HOME=/opt/jdks/latest-17 /opt/maven/latest/bin/mvn -Prun-its clean install(761 integration tests, 0 failures, 0 errors)nice -n 10 /opt/maven/latest/bin/mvn clean test -pl surefire-providers/common-java5,surefire-providers/surefire-junit-platform(passed; 85 JUnit Platform provider tests)initializationError)nice -n 10 /opt/maven/latest/bin/mvn clean verify -pl surefire-its -Prun-its -Dit.test=Surefire2274FailsafeFlakeCountIT -Dmaven.build.cache.enabled=false(passed on Java 8; nested Failsafe build failed atverifyas expected with 2 flakes)nice -n 10 /opt/maven/latest/bin/mvn clean test -pl maven-failsafe-plugin -Dtest=RunResultTest -Dmaven.build.cache.enabled=false(7 tests, 0 failures, 0 errors)nice -n 10 /opt/maven/latest/bin/mvn clean test -pl surefire-providers/surefire-junit-platform -Dmaven.build.cache.enabled=false(87 tests, 0 failures, 0 errors)nice -n 10 /opt/maven/latest/bin/mvn clean verify -pl surefire-its -Prun-its -Dit.test=Surefire2300BeforeAllAssumptionIT,JUnit5BeforeAllContainerFailureIT,JUnit4PlatformFailingBeforeAllRerunIT -Dmaven.build.cache.enabled=false(3 tests, 0 failures, 0 errors)