From 399e2868bf70191f4da64a86a96533c309b559bc Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Mon, 4 Dec 2023 11:48:10 +0100 Subject: [PATCH 1/2] Add out-of-the-box support for develocity testing annotations Signed-off-by: Simon Taddiken --- .../internal/filter/ClassRetryMatcher.java | 3 +- .../testframework/JUnit4FuncTest.groovy | 17 +++++++--- .../testframework/JUnit5FuncTest.groovy | 32 +++++++++++-------- .../testframework/SpockBaseFuncTest.groovy | 17 +++++++--- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/plugin/src/main/java/org/gradle/testretry/internal/filter/ClassRetryMatcher.java b/plugin/src/main/java/org/gradle/testretry/internal/filter/ClassRetryMatcher.java index 400042e6..13947f1c 100644 --- a/plugin/src/main/java/org/gradle/testretry/internal/filter/ClassRetryMatcher.java +++ b/plugin/src/main/java/org/gradle/testretry/internal/filter/ClassRetryMatcher.java @@ -29,7 +29,8 @@ public class ClassRetryMatcher { private static final List IMPLICIT_INCLUDE_ANNOTATION_CLASSES = unmodifiableList(asList( "spock.lang.Stepwise", // Spock's @Stepwise annotated classes must be retried as a whole - "com.gradle.enterprise.testing.annotations.ClassRetry" //common testing annotations + "com.gradle.enterprise.testing.annotations.ClassRetry", // common testing annotations + "com.gradle.develocity.testing.annotations.ClassRetry" // common testing annotations )); private final AnnotationInspector annotationInspector; diff --git a/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit4FuncTest.groovy b/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit4FuncTest.groovy index 0288c943..a8affb90 100644 --- a/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit4FuncTest.groovy +++ b/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit4FuncTest.groovy @@ -536,13 +536,17 @@ class JUnit4FuncTest extends AbstractFrameworkFuncTest { gradleVersion << GRADLE_VERSIONS_UNDER_TEST } - def "can rerun on whole class via annotation (gradle version #gradleVersion)"() { + def "can rerun on whole class via annotation (gradle version #gradleVersion and retry annotation #retryAnnotation)"() { given: buildFile << """ + dependencies { + testImplementation 'com.gradle:develocity-testing-annotations:2.0' + testImplementation 'com.gradle:gradle-enterprise-testing-annotations:1.1.2' + } test.retry { maxRetries = 1 classRetry { - includeAnnotationClasses.add('*ClassRetry') + includeAnnotationClasses.add('*CustomClassRetry') } } """ @@ -556,7 +560,7 @@ class JUnit4FuncTest extends AbstractFrameworkFuncTest { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) - public @interface ClassRetry { + public @interface CustomClassRetry { } """ @@ -564,7 +568,7 @@ class JUnit4FuncTest extends AbstractFrameworkFuncTest { writeJavaTestSource """ package acme; - @ClassRetry + @$retryAnnotation public class FlakyTests { @org.junit.Test public void a() { @@ -588,7 +592,10 @@ class JUnit4FuncTest extends AbstractFrameworkFuncTest { } where: - gradleVersion << GRADLE_VERSIONS_UNDER_TEST + [gradleVersion, retryAnnotation] << [ + GRADLE_VERSIONS_UNDER_TEST, + ["acme.CustomClassRetry", "com.gradle.enterprise.testing.annotations.ClassRetry", "com.gradle.develocity.testing.annotations.ClassRetry"] + ].combinations() } def "handles flaky setup that prevents the retries of initially failed methods (gradle version #gradleVersion)"() { 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 217f3952..493aac24 100644 --- a/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit5FuncTest.groovy +++ b/plugin/src/test/groovy/org/gradle/testretry/testframework/JUnit5FuncTest.groovy @@ -320,13 +320,17 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { gradleVersion << GRADLE_VERSIONS_UNDER_TEST } - def "can rerun on whole class via annotation (gradle version #gradleVersion)"() { + def "can rerun on whole class via annotation (gradle version #gradleVersion and retry annotation #retryAnnotation)"() { given: buildFile << """ + dependencies { + testImplementation 'com.gradle:develocity-testing-annotations:2.0' + testImplementation 'com.gradle:gradle-enterprise-testing-annotations:1.1.2' + } test.retry { maxRetries = 1 classRetry { - includeAnnotationClasses.add('*ClassRetry') + includeAnnotationClasses.add('*CustomClassRetry') } } """ @@ -340,7 +344,7 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) - public @interface ClassRetry { + public @interface CustomClassRetry { } """ @@ -348,7 +352,7 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { writeJavaTestSource """ package acme; - @ClassRetry + @$retryAnnotation class FlakyTests { @org.junit.jupiter.api.Test void a() { @@ -372,7 +376,10 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { } where: - gradleVersion << GRADLE_VERSIONS_UNDER_TEST + [gradleVersion, retryAnnotation] << [ + GRADLE_VERSIONS_UNDER_TEST, + ["acme.CustomClassRetry", "com.gradle.enterprise.testing.annotations.ClassRetry", "com.gradle.develocity.testing.annotations.ClassRetry"] + ].combinations() } def "handles flaky setup that prevents the retries of initially failed methods (gradle version #gradleVersion)"() { @@ -500,19 +507,19 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { (1..2).collect { writeJavaTestSource """ package acme; - + import org.junit.jupiter.api.*; - + public class Test${it} { @Test void testOk() { } - + @Test void testFlaky() { ${flakyAssert("${it}")} - } - + } + } """ } @@ -522,7 +529,7 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { import org.junit.jupiter.api.*; import org.junit.platform.suite.api.*; - + @Suite @SelectClasses({Test1.class,Test2.class}) public class TestSuite { @@ -542,7 +549,6 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { it.count("${classAndMethodForSuite("Test2", "testOk()", gradleVersion)} PASSED") == 1 it.count("${classAndMethodForSuite("Test2", "testFlaky()", gradleVersion)} FAILED") == 1 it.count("${classAndMethodForSuite("Test2", "testFlaky()", gradleVersion)} PASSED") == 1 - } where: @@ -582,7 +588,7 @@ class JUnit5FuncTest extends AbstractFrameworkFuncTest { @Test void testOk() { } - + @Test void testFlaky() { ${flakyAssert("nested1")} diff --git a/plugin/src/test/groovy/org/gradle/testretry/testframework/SpockBaseFuncTest.groovy b/plugin/src/test/groovy/org/gradle/testretry/testframework/SpockBaseFuncTest.groovy index 67e2ad30..be55e753 100644 --- a/plugin/src/test/groovy/org/gradle/testretry/testframework/SpockBaseFuncTest.groovy +++ b/plugin/src/test/groovy/org/gradle/testretry/testframework/SpockBaseFuncTest.groovy @@ -312,13 +312,17 @@ abstract class SpockBaseFuncTest extends AbstractFrameworkFuncTest { gradleVersion << GRADLE_VERSIONS_UNDER_TEST } - def "can rerun on whole class via annotation (gradle version #gradleVersion)"() { + def "can rerun on whole class via annotation (gradle version #gradleVersion and retry annotation #retryAnnotation)"() { given: buildFile << """ + dependencies { + testImplementation 'com.gradle:develocity-testing-annotations:2.0' + testImplementation 'com.gradle:gradle-enterprise-testing-annotations:1.1.2' + } test.retry { maxRetries = 1 classRetry { - includeAnnotationClasses.add('*ClassRetry') + includeAnnotationClasses.add('*CustomClassRetry') } } """ @@ -333,7 +337,7 @@ abstract class SpockBaseFuncTest extends AbstractFrameworkFuncTest { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) - @interface ClassRetry { + @interface CustomClassRetry { } """ @@ -341,7 +345,7 @@ abstract class SpockBaseFuncTest extends AbstractFrameworkFuncTest { writeGroovyTestSource """ package acme - @ClassRetry + @$retryAnnotation class FlakyTests extends spock.lang.Specification { def "parentTest"() { expect: @@ -372,7 +376,10 @@ abstract class SpockBaseFuncTest extends AbstractFrameworkFuncTest { } where: - gradleVersion << GRADLE_VERSIONS_UNDER_TEST + [gradleVersion, retryAnnotation] << [ + GRADLE_VERSIONS_UNDER_TEST, + ["acme.CustomClassRetry", "com.gradle.enterprise.testing.annotations.ClassRetry", "com.gradle.develocity.testing.annotations.ClassRetry"] + ].combinations() } def "only track a @Retry test method once to ensure it was re-ran successfully"() { From d292e2580401c767d81d4ce6d6b887e5db4d92d6 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Mon, 4 Dec 2023 11:48:24 +0100 Subject: [PATCH 2/2] Rename GE section to Develocity Signed-off-by: Simon Taddiken --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index f883e041..29700763 100644 --- a/README.adoc +++ b/README.adoc @@ -401,7 +401,7 @@ This means that all executions of the same test may not be grouped in the consol image:gradle-console-test-retry-reporting.png[Gradle console reporting, align="center", title=Flaky test Gradle console output] -=== Gradle Enterprise +=== Develocity Gradle build scans (`--scan` option) report discrete test executions as "Execution [N of total]" and will mark a test with both a _failed_ and then a _passed_ outcome as _flaky_.