Skip to content

Fix #3303: distinguish JUnit 6 ParameterizedClass invocations - #3432

Open
AzazelSensei wants to merge 2 commits into
apache:masterfrom
AzazelSensei:fix/3303-parameterized-class-rerun
Open

Fix #3303: distinguish JUnit 6 ParameterizedClass invocations#3432
AzazelSensei wants to merge 2 commits into
apache:masterfrom
AzazelSensei:fix/3303-parameterized-class-rerun

Conversation

@AzazelSensei

Copy link
Copy Markdown

Following this checklist to help us incorporate your contribution quickly and easily:

  • Each commit in the pull request should have a meaningful subject line and body.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Run mvn clean install to make sure basic checks pass. A more thorough check will be performed on your pull request automatically.
  • You have run the integration tests successfully (mvn -Prun-its clean install).

Targeted module tests: mvn -pl surefire-providers/surefire-junit-platform test -Dtest=RunListenerAdapterTest,JUnitPlatformProviderTest (75 passed). Did not run the full ITS profile locally.

Fixes #3303.

rerunFailingTestsCount treats two reports with the same class+method name as one test. JUnit 5 @ParameterizedTest already puts [N] on the method legacy name. JUnit 6 @ParameterizedClass does not: the index lives on a [class-template-invocation:#N] parent with a ClassSource, so hasParameterizedParent misses it and both invocations look like testSomething(). A fail then a pass on the next index gets collapsed into a flake/pass.

This reads that unique-id segment and appends [N] when the method name does not already have it.

@ParameterizedClass uses a [class-template-invocation:#N] unique-id
segment and a ClassSource parent. The method legacy name no longer
carries [N], so rerunFailingTestsCount merged a pass+fail pair into
one flaky name.

Append that index to the reported method name, same as we already do
for @ParameterizedTest.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes rerun aggregation for JUnit 6 parameterized-class invocations by deriving invocation indices from unique IDs.

Changes:

  • Appends class-template invocation indices to report names.
  • Adds regression coverage for distinct invocations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
RunListenerAdapter.java Extracts and adds invocation indices.
RunListenerAdapterTest.java Tests distinct report names.
Suppressed comments (1)

surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java:505

  • The suffix check misdetects JUnit 6.1+ names for parameterized methods. Those legacy names already place the class index before the method invocation index; for example, class #1/method #2 is method()[1][2], so this code appends another [1] and reports method()[1][2][1]. Detect the class-index sequence structurally rather than requiring it at the end, and cover this newer format.
            if (classTemplateInvocationIndex != null
                    && !methodDesc.endsWith("[" + classTemplateInvocationIndex + "]")) {
                methodDesc = methodDesc + "[" + classTemplateInvocationIndex + "]";

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

return null;
}
String marker = "[class-template-invocation:";
int start = uniqueId.lastIndexOf(marker);
Collect every class-template-invocation index so nested parameterizations stay distinct. Do not re-append when the legacy name already carries the class index.
@AzazelSensei

Copy link
Copy Markdown
Author

Nested class-template indices are all kept now, so outer #1/inner #1 and outer #2/inner #1 no longer collapse. Also stopped appending again when the legacy name already has the class index.

if (uniqueId == null) {
return "";
}
String marker = "[class-template-invocation:";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything available to extract segments from a uniqueId representation rather than parsing manually?
Maybe?

UniqueId.parse(uniqueId).getSegments()

boolean hasLegacyDescription = description.startsWith(methodName + '(');
boolean hasDisplayName = !equalDescriptions || !hasLegacyDescription;
String methodDesc = parameterized ? description : methodName;
// JUnit 6.1+ already puts the class index before a method invocation index

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the class-invocation index is appended after the method index (foo()[m][c]), or collapses on the diagonal (c==m → foo()[c]). This contradicts the [class][method].
2 class invocations × method invocations #1/#2 → foo(String)[1], foo(String)[2][1], foo(String)[1][2], foo(String)[2]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rerunFailingTestsCount incorrectly marks failed ParameterizedClass test as pass

3 participants