diff --git a/.kotlin/sessions/kotlin-compiler-12245719162864461619.salive b/.kotlin/sessions/kotlin-compiler-12245719162864461619.salive new file mode 100644 index 00000000..e69de29b diff --git a/plugin/src/main/java/org/gradle/testretry/internal/executer/framework/BaseJunitTestFrameworkStrategy.java b/plugin/src/main/java/org/gradle/testretry/internal/executer/framework/BaseJunitTestFrameworkStrategy.java index e5fe9de4..42652525 100644 --- a/plugin/src/main/java/org/gradle/testretry/internal/executer/framework/BaseJunitTestFrameworkStrategy.java +++ b/plugin/src/main/java/org/gradle/testretry/internal/executer/framework/BaseJunitTestFrameworkStrategy.java @@ -35,7 +35,7 @@ abstract class BaseJunitTestFrameworkStrategy implements TestFrameworkStrategy { public static final Logger LOGGER = LoggerFactory.getLogger(JunitTestFrameworkStrategy.class); - private static final Pattern PARAMETERIZED_SUFFIX_PATTERN = Pattern.compile("(?:\\([^)]*?\\))?(?:\\[[^]]*?])?$"); + private static final Pattern PARAMETERIZED_SUFFIX_PATTERN = Pattern.compile("(?:\\([^)]*?\\))?(?:\\[[^]]*?])*$"); private static final String ERROR_SYNTHETIC_TESTNG_CLASS_NAME = "UnknownClass"; static final Set ERROR_SYNTHETIC_TEST_NAMES = Collections.unmodifiableSet( new HashSet<>(Arrays.asList( @@ -159,10 +159,11 @@ private boolean processTestNGTest(TestFilterBuilder filters, TestsReader testsRe private void addPotentiallyParameterizedSuffixed(TestFilterBuilder filters, String className, String name) { // It's a common pattern to add all the parameters on the end of a literal method name with [] - // The regex takes care of removing trailing (...) or (...)[...], for e.g. the following cases + // The regex takes care of removing trailing (...) or (...)[...], or (...)[...][...] for e.g. the following cases // * `test that contains (parentheses)()` // * `test that contains (parentheses)(int, int)[1]` // * `test(1, true) [0]` + // * `dynamicContainerTest()[1][1]` String strippedParameterName = PARAMETERIZED_SUFFIX_PATTERN.matcher(name).replaceAll(""); filters.test(className, strippedParameterName); filters.test(className, name); diff --git a/plugin/src/test/groovy/org/gradle/testretry/ParenthesesFuncTest.groovy b/plugin/src/test/groovy/org/gradle/testretry/ParenthesesFuncTest.groovy index 9662e5a6..838c42d0 100644 --- a/plugin/src/test/groovy/org/gradle/testretry/ParenthesesFuncTest.groovy +++ b/plugin/src/test/groovy/org/gradle/testretry/ParenthesesFuncTest.groovy @@ -157,7 +157,7 @@ class ParenthesesFuncTest extends AbstractPluginFuncTest { private static String junit5ParameterizedTestWithParentheses() { """ package acme - + import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -170,7 +170,7 @@ class ParenthesesFuncTest extends AbstractPluginFuncTest { assert(a == b) ${flakyAssert()} } - + companion object { @JvmStatic fun data() = listOf( diff --git a/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit5FuncTest.groovy b/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit5FuncTest.groovy index 3e8ef984..9760a346 100644 --- a/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit5FuncTest.groovy +++ b/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit5FuncTest.groovy @@ -16,6 +16,7 @@ package org.gradle.testretry.testframework import org.gradle.testretry.AbstractFrameworkFuncTest +import org.gradle.util.GradleVersion import javax.annotation.Nullable @@ -718,6 +719,66 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { gradleVersion << GRADLE_VERSIONS_UNDER_TEST } + def "supports dynamic tests (gradle version #gradleVersion)"() { + given: + buildFile << """ + test { + retry { + maxRetries = 1 + } + } + """ + + writeJavaTestSource """ + package acme; + + import org.junit.jupiter.api.*; + import java.util.stream.Stream; + + class MyTest { + @TestFactory + DynamicContainer dynamicContainerTest() { + return DynamicContainer.dynamicContainer("container", Stream.of( + DynamicTest.dynamicTest("test name 1", () -> { + ${flakyAssert()} + }) + )); + } + } + """ + + when: + def result = gradleRunner(gradleVersion).build() + + then: + def gv = GradleVersion.version(gradleVersion) + def testname = dynamicTestName(gv) + + with(result.output) { + it.count("${testname} FAILED") == 1 + it.count("${testname} PASSED") == 1 + } + + where: + gradleVersion << GRADLE_VERSIONS_UNDER_TEST + } + + private static String dynamicTestName(GradleVersion gv) { + if (gv >= GradleVersion.version("8.8")) { + return 'MyTest > dynamicContainerTest() > container > test name 1' + } else if ((gv >= GradleVersion.version("8.1") && gv < GradleVersion.version("8.8")) || (gv >= GradleVersion.version("7.6") && gv < GradleVersion.version("8.0"))) { + return 'MyTest > dynamicContainerTest() > container > acme.MyTest.test name 1' + } else if ((gv >= GradleVersion.version("7.0") && gv < GradleVersion.version("7.6")) || (gv >= GradleVersion.version("8.0") && gv < GradleVersion.version("8.1"))) { + return 'MyTest > dynamicContainerTest() > container > acme.MyTest.dynamicContainerTest()[1][1]' + } else if ((gv >= GradleVersion.version("6.7") && gv < GradleVersion.version("7.0")) || (gv >= GradleVersion.version("6.1") && gv < GradleVersion.version("6.6"))) { + return 'MyTest > test name 1' + } else if (gv >= GradleVersion.version("6.6") && gv < GradleVersion.version("6.7")) { + return 'acme.MyTest > test name 1' + } else { + return 'acme.MyTest > dynamicContainerTest()[1][1]' + } + } + String reportedTestName(String testName) { testName + "()" }