From 16dd9e7abba4a49d46eba63a5f1fd9cca6573dc7 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Tue, 30 Aug 2022 17:01:13 -0400 Subject: [PATCH 01/17] Accessing test options no longer warns, but locks in test framework selection --- .../testing/TestTaskIntegrationTest.groovy | 45 ++++++------------- .../TestSuitesIntegrationTest.groovy | 22 ++++----- .../org/gradle/api/tasks/testing/Test.java | 45 +++++-------------- 3 files changed, 31 insertions(+), 81 deletions(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy index fb78e1c9df73..be51036c23f9 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy @@ -16,6 +16,7 @@ package org.gradle.testing +import org.gradle.api.GradleException import org.gradle.integtests.fixtures.ToBeFixedForConfigurationCache import org.gradle.integtests.fixtures.TargetCoverage import org.gradle.test.fixtures.file.TestFile @@ -282,7 +283,7 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { extraArgs << [[], ["--tests", "MyTest"]] } - def "options set prior to setting same test framework will warn and have no effect"() { + def "options set prior to setting same test framework will remain in effect and not cause error"() { ignoreWhenJUnitPlatform() given: @@ -302,22 +303,16 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { } useJUnit() } - - tasks.register('verifyTestOptions') { - doLast { - assert tasks.getByName("test").getOptions().getClass() == JUnitOptions - assert !tasks.getByName("test").getOptions().getExcludeCategories().contains("Slow") - } - } """.stripIndent() - executer.expectDeprecationWarning("Accessing test options prior to setting test framework has been deprecated.") + when: + fails("test") - expect: - succeeds("test", "verifyTestOptions", "--warn") + then: + failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: JUnitTestFramework.") } - def "options set prior to changing test framework will produce additional warning and have no effect"() { + def "options set prior to changing test framework will cause error"() { ignoreWhenJUnitPlatform() given: @@ -340,21 +335,13 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { test { useJUnitPlatform() } - - tasks.register('verifyTestOptions') { - doLast { - assert tasks.getByName("test").getOptions().getClass() == JUnitPlatformOptions - } - } """.stripIndent() - executer.expectDeprecationWarning("Accessing test options prior to setting test framework has been deprecated.") - when: - succeeds("test", "verifyTestOptions", "--warn") + fails("test") then: - outputContains("Test framework is changing from 'JUnitTestFramework', previous option configuration would not be applicable.") + failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: JUnitPlatformTestFramework.") } def "options accessed and not explicitly configured prior to setting test framework will also warn"() { @@ -377,19 +364,13 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { test { useJUnitPlatform() } - - tasks.register('verifyTestOptions') { - doLast { - assert options.getClass() == JUnitOptions - assert tasks.getByName("test").getOptions().getClass() == JUnitPlatformOptions - } - } """.stripIndent() - executer.expectDeprecationWarning("Accessing test options prior to setting test framework has been deprecated.") + when: + fails("test") - expect: - succeeds("test", "verifyTestOptions", "--warn") + then: + failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: JUnitPlatformTestFramework.") } def "options configured after setting test framework works"() { diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy index 350611a3b3db..7127b2a20384 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy @@ -480,8 +480,7 @@ class TestSuitesIntegrationTest extends AbstractIntegrationSpec { succeeds("checkConfiguration") } - // TODO: Test Framework Selection - Revert this to may NOT in Gradle 8 - def "test framework MAY be changed once options have been used with test suites"() { + def "test framework can not be changed once options have been used with test suites"() { buildFile << """ plugins { id 'java' @@ -511,14 +510,14 @@ class TestSuitesIntegrationTest extends AbstractIntegrationSpec { check.dependsOn testing.suites """ - executer.expectDeprecationWarning("Accessing test options prior to setting test framework has been deprecated. This is scheduled to be removed in Gradle 8.0.") + when: + fails("check") - expect: - succeeds("check") + then: + failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: TestNGTestFramework.") } - // This checks for backwards compatibility with builds that may rely on this - def "can change the test framework multiple times before execution when not using test suites"() { + def "can change not the test framework multiple times before execution when not using test suites"() { given: buildFile << """ plugins { @@ -550,16 +549,11 @@ class TestSuitesIntegrationTest extends AbstractIntegrationSpec { } """ - executer.expectDeprecationWarning("Accessing test options prior to setting test framework has been deprecated. This is scheduled to be removed in Gradle 8.0.") - executer.expectDeprecationWarning("Accessing test options prior to setting test framework has been deprecated. This is scheduled to be removed in Gradle 8.0.") - when: - succeeds("test") + fails("test") then: - executedAndNotSkipped(":test") - DefaultTestExecutionResult result = new DefaultTestExecutionResult(testDirectory) - result.assertTestClassesExecuted("SomeTest") + failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: JUnitPlatformTestFramework.") } // This is not the behavior we want in the long term because this makes build configuration sensitive to the order diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java index 0beab8064d3e..bfc8361176d0 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java @@ -21,6 +21,7 @@ import groovy.lang.DelegatesTo; import org.gradle.StartParameter; import org.gradle.api.Action; +import org.gradle.api.GradleException; import org.gradle.api.Incubating; import org.gradle.api.JavaVersion; import org.gradle.api.NonNullApi; @@ -69,7 +70,6 @@ import org.gradle.internal.Factory; import org.gradle.internal.actor.ActorFactory; import org.gradle.internal.concurrent.CompositeStoppable; -import org.gradle.internal.deprecation.DeprecationLogger; import org.gradle.internal.jvm.DefaultModularitySpec; import org.gradle.internal.jvm.JavaModuleDetector; import org.gradle.internal.jvm.UnsupportedJavaRuntimeException; @@ -172,6 +172,12 @@ public class Test extends AbstractTestTask implements JavaForkOptions, PatternFi private FileCollection classpath; private final ConfigurableFileCollection stableClasspath; private final Property testFramework; + + /* + * These fields are status variables that are used to keep track of the state of the test task + * to prevent potential errors or unexpected behavior caused by setting the test framework + * after setting options. + */ private boolean userHasConfiguredTestFramework; private boolean optionsAccessed; @@ -920,31 +926,6 @@ public TestFramework testFramework(@Nullable Closure testFrameworkConfigure) { useJUnit(testFrameworkConfigure); } - // To maintain backwards compatibility with builds that may configure the test framework - // multiple times for a single task--either switching between frameworks or overwriting - // the existing configuration for a test framework--we need to keep track if the user has - // explicitly set a test framework - // With test suites, users should never need to call the useXXX methods, so we can warn if - // them from doing something like this (for now, in order to preserve existing builds). - // This behavior should be restored to fail fast once again with the next major version. - // - // testTask.configure { - // options { - // /* configure JUnit Platform */ - // } - // } - // testTask.configure { - // useJUnit() - // options { - // /* configure JUnit */ - // } - // } - - // TODO: Test Framework Selection - Restore this to re-enable fail-fast behavior for Gradle 8 -// if (!userHasConfiguredTestFramework) { -// testFramework.finalizeValue(); -// } - return testFramework.get(); } @@ -988,16 +969,10 @@ TestFramework useTestFramework(TestFramework testFramework) { } private TestFramework useTestFramework(TestFramework testFramework, @Nullable Action testFrameworkConfigure) { + final TestFramework oldFramework = Test.this.testFramework.get(); + if (optionsAccessed) { - DeprecationLogger.deprecateAction("Accessing test options prior to setting test framework") - .withContext("\nTest options have already been accessed for task: '" + getProject().getName() + ":" + getName() + "' prior to setting the test framework to: '" + testFramework.getClass().getSimpleName() + "'. Any previous configuration will be discarded.\n") - .willBeRemovedInGradle8() - .withDslReference(Test.class, "options") - .nagUser(); - - if (!this.testFramework.get().getClass().equals(testFramework.getClass())) { - getLogger().warn("Test framework is changing from '{}', previous option configuration would not be applicable.", this.testFramework.get().getClass().getSimpleName()); - } + throw new GradleException("Cannot set test framework after accessing test options. Framework was previously: " + oldFramework.getClass().getSimpleName() + ", attempting to set: " + testFramework.getClass().getSimpleName() + "." ); } userHasConfiguredTestFramework = true; From 22dfccb14331f686248aa5ae054622d335a16663 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 31 Aug 2022 09:49:34 -0400 Subject: [PATCH 02/17] Clean style violations --- .../groovy/org/gradle/testing/TestTaskIntegrationTest.groovy | 1 - .../gradle/testing/testsuites/TestSuitesIntegrationTest.groovy | 1 - .../src/main/java/org/gradle/api/tasks/testing/Test.java | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy index be51036c23f9..4e4cc975d210 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy @@ -16,7 +16,6 @@ package org.gradle.testing -import org.gradle.api.GradleException import org.gradle.integtests.fixtures.ToBeFixedForConfigurationCache import org.gradle.integtests.fixtures.TargetCoverage import org.gradle.test.fixtures.file.TestFile diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy index 7127b2a20384..70f86940e07b 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy @@ -23,7 +23,6 @@ import org.gradle.api.plugins.jvm.internal.DefaultJvmTestSuite import org.gradle.api.tasks.testing.junit.JUnitOptions import org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions import org.gradle.integtests.fixtures.AbstractIntegrationSpec -import org.gradle.integtests.fixtures.DefaultTestExecutionResult import org.gradle.integtests.fixtures.JUnitXmlTestExecutionResult import spock.lang.Issue diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java index bfc8361176d0..65a478b9ecd7 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java @@ -972,7 +972,7 @@ private TestFramework useTestFramework(TestFram final TestFramework oldFramework = Test.this.testFramework.get(); if (optionsAccessed) { - throw new GradleException("Cannot set test framework after accessing test options. Framework was previously: " + oldFramework.getClass().getSimpleName() + ", attempting to set: " + testFramework.getClass().getSimpleName() + "." ); + throw new GradleException("Cannot set test framework after accessing test options. Framework was previously: " + oldFramework.getClass().getSimpleName() + ", attempting to set: " + testFramework.getClass().getSimpleName() + "."); } userHasConfiguredTestFramework = true; From 899903b30d612d91ce978f0fc70064b67891971b Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 31 Aug 2022 15:13:09 -0400 Subject: [PATCH 03/17] Correct name of test method --- .../groovy/org/gradle/testing/TestTaskIntegrationTest.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy index 4e4cc975d210..149852a9088b 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy @@ -282,7 +282,7 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { extraArgs << [[], ["--tests", "MyTest"]] } - def "options set prior to setting same test framework will remain in effect and not cause error"() { + def "options set prior to setting same test framework will cause error"() { ignoreWhenJUnitPlatform() given: From 45363ed2f742b22e9d4c854317501583d7f6b156 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Mon, 12 Sep 2022 11:56:06 -0400 Subject: [PATCH 04/17] Update error message format when attempting to improperly set test framework after options are already set - Also provide each test framework with a display name property for user-facing references. --- .../org/gradle/testing/TestTaskIntegrationTest.groovy | 6 +++--- .../testing/testsuites/TestSuitesIntegrationTest.groovy | 4 ++-- .../gradle/api/internal/tasks/testing/TestFramework.java | 6 ++++++ .../internal/tasks/testing/junit/JUnitTestFramework.java | 5 +++++ .../testing/junitplatform/JUnitPlatformTestFramework.java | 5 +++++ .../internal/tasks/testing/testng/TestNGTestFramework.java | 4 ++++ .../src/main/java/org/gradle/api/tasks/testing/Test.java | 5 ++++- 7 files changed, 29 insertions(+), 6 deletions(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy index 149852a9088b..5e6cdeb7b473 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy @@ -308,7 +308,7 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { fails("test") then: - failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: JUnitTestFramework.") + failure.assertHasErrorOutput("You cannot set the test framework to: JUnit 4 after accessing test options. The current framework is: JUnit 4.") } def "options set prior to changing test framework will cause error"() { @@ -340,7 +340,7 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { fails("test") then: - failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: JUnitPlatformTestFramework.") + failure.assertHasErrorOutput("You cannot change the test framework to: JUnit Platform after accessing test options. The current framework is: JUnit 4.") } def "options accessed and not explicitly configured prior to setting test framework will also warn"() { @@ -369,7 +369,7 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { fails("test") then: - failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: JUnitPlatformTestFramework.") + failure.assertHasErrorOutput("You cannot change the test framework to: JUnit Platform after accessing test options. The current framework is: JUnit 4.") } def "options configured after setting test framework works"() { diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy index 70f86940e07b..27ed7f0ddb56 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy @@ -513,7 +513,7 @@ class TestSuitesIntegrationTest extends AbstractIntegrationSpec { fails("check") then: - failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: TestNGTestFramework.") + failure.assertHasErrorOutput("You cannot change the test framework to: Test NG after accessing test options. The current framework is: JUnit 4.") } def "can change not the test framework multiple times before execution when not using test suites"() { @@ -552,7 +552,7 @@ class TestSuitesIntegrationTest extends AbstractIntegrationSpec { fails("test") then: - failure.assertHasErrorOutput("Cannot set test framework after accessing test options. Framework was previously: JUnitTestFramework, attempting to set: JUnitPlatformTestFramework.") + failure.assertHasErrorOutput("You cannot change the test framework to: JUnit Platform after accessing test options. The current framework is: JUnit 4.") } // This is not the behavior we want in the long term because this makes build configuration sensitive to the order diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/TestFramework.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/TestFramework.java index 6d2a7f51934a..d343e342186a 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/TestFramework.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/TestFramework.java @@ -61,4 +61,10 @@ public interface TestFramework extends Closeable { */ @Internal List getTestWorkerImplementationModules(); + + /** + * This property controls how we describe this test framework to the user (i.e., in error messages). + */ + @Internal + String getDisplayName(); } diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/junit/JUnitTestFramework.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/junit/JUnitTestFramework.java index 66361d1614e0..5265543e9d9c 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/junit/JUnitTestFramework.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/junit/JUnitTestFramework.java @@ -73,6 +73,11 @@ public List getTestWorkerImplementationModules() { return Collections.emptyList(); } + @Override + public String getDisplayName() { + return "JUnit 4"; + } + @Override public JUnitOptions getOptions() { return options; diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/junitplatform/JUnitPlatformTestFramework.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/junitplatform/JUnitPlatformTestFramework.java index 6d50d80a2442..fb9b2d900b08 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/junitplatform/JUnitPlatformTestFramework.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/junitplatform/JUnitPlatformTestFramework.java @@ -75,6 +75,11 @@ public List getTestWorkerImplementationModules() { return ImmutableList.of("junit-platform-engine", "junit-platform-launcher", "junit-platform-commons"); } + @Override + public String getDisplayName() { + return "JUnit Platform"; + } + @Override public JUnitPlatformOptions getOptions() { return options; diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/testng/TestNGTestFramework.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/testng/TestNGTestFramework.java index 21ad5630ba7f..f6d4be6d4899 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/testng/TestNGTestFramework.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/internal/tasks/testing/testng/TestNGTestFramework.java @@ -171,6 +171,10 @@ public List getTestWorkerImplementationModules() { return Collections.emptyList(); } + @Override + public String getDisplayName() { + return "Test NG"; + } @Override public TestNGOptions getOptions() { return options; diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java index 65a478b9ecd7..fc6189f35ab4 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java @@ -972,7 +972,10 @@ private TestFramework useTestFramework(TestFram final TestFramework oldFramework = Test.this.testFramework.get(); if (optionsAccessed) { - throw new GradleException("Cannot set test framework after accessing test options. Framework was previously: " + oldFramework.getClass().getSimpleName() + ", attempting to set: " + testFramework.getClass().getSimpleName() + "."); + throw new GradleException(String.format("You cannot %s the test framework to: %s after accessing test options. The current framework is: %s.", + testFramework.getClass() == oldFramework.getClass() ? "set" : "change", + testFramework.getDisplayName(), + oldFramework.getDisplayName())); } userHasConfiguredTestFramework = true; From 1f54a0417e40a3c52b879198280baf339033ccf9 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Mon, 12 Sep 2022 11:56:55 -0400 Subject: [PATCH 05/17] Optimize framework creation now that reseting framework after options set is blocked elsewhere --- .../jvm/internal/DefaultJvmTestSuite.java | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java b/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java index def496393bd6..f9a666ae14d2 100644 --- a/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java +++ b/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java @@ -26,7 +26,6 @@ import org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyAdder; import org.gradle.api.internal.tasks.AbstractTaskDependency; import org.gradle.api.internal.tasks.TaskDependencyResolveContext; -import org.gradle.api.internal.tasks.testing.TestFramework; import org.gradle.api.internal.tasks.testing.filter.DefaultTestFilter; import org.gradle.api.internal.tasks.testing.junit.JUnitTestFramework; import org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestFramework; @@ -46,8 +45,6 @@ import javax.annotation.Nullable; import javax.inject.Inject; -import java.util.HashMap; -import java.util.Map; public abstract class DefaultJvmTestSuite implements JvmTestSuite { public enum Frameworks { @@ -149,24 +146,21 @@ public DefaultJvmTestSuite(String name, DependencyFactory dependencyFactory, Con addDefaultTestTarget(); - // Until the values here can be finalized upon the user setting them (see the org.gradle.api.tasks.testing.Test#testFramework(Closure) method), - // in Gradle 8, we will be executing the provider lambda used as the convention multiple times. So make sure, within a Test Suite, that we - // always return the same one via computeIfAbsent() against this map. - final Map frameworkLookup = new HashMap<>(3); - + // The values here can now be considered finalized upon the user setting them (see the org.gradle.api.tasks.testing.Test#testFramework(Closure) method). So + // there is now no need to use a map to ensure a given test framework is only created once. this.targets.withType(JvmTestSuiteTarget.class).configureEach(target -> { target.getTestTask().configure(task -> { task.getTestFrameworkProperty().convention(getVersionedTestingFramework().map(vtf -> { switch(vtf.type) { case NONE: // fall-through case JUNIT4: - return frameworkLookup.computeIfAbsent(vtf.type, f -> new JUnitTestFramework(task, (DefaultTestFilter) task.getFilter())); + return new JUnitTestFramework(task, (DefaultTestFilter) task.getFilter()); case KOTLIN_TEST: // fall-through case JUNIT_JUPITER: // fall-through case SPOCK: - return frameworkLookup.computeIfAbsent(vtf.type, f -> new JUnitPlatformTestFramework((DefaultTestFilter) task.getFilter())); + return new JUnitPlatformTestFramework((DefaultTestFilter) task.getFilter()); case TESTNG: - return frameworkLookup.computeIfAbsent(vtf.type, f -> new TestNGTestFramework(task, task.getClasspath(), (DefaultTestFilter) task.getFilter(), getObjectFactory())); + return new TestNGTestFramework(task, task.getClasspath(), (DefaultTestFilter) task.getFilter(), getObjectFactory()); default: throw new IllegalStateException("do not know how to handle " + vtf); } From 50a4758dd061109e266709be5ef31fddd96bd355 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Mon, 12 Sep 2022 15:11:19 -0400 Subject: [PATCH 06/17] Update name of test to reflect new behavior --- .../groovy/org/gradle/testing/TestTaskIntegrationTest.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy index 5e6cdeb7b473..3c6e4e6b5909 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestTaskIntegrationTest.groovy @@ -343,7 +343,7 @@ class TestTaskIntegrationTest extends JUnitMultiVersionIntegrationSpec { failure.assertHasErrorOutput("You cannot change the test framework to: JUnit Platform after accessing test options. The current framework is: JUnit 4.") } - def "options accessed and not explicitly configured prior to setting test framework will also warn"() { + def "options accessed and not explicitly configured prior to setting test framework also fails"() { given: file('src/test/java/MyTest.java') << junitJupiterStandaloneTestClass() From d21e077a7c05f9d0370d98a0b841f0b4de93df01 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Tue, 13 Sep 2022 12:31:53 -0400 Subject: [PATCH 07/17] Restore map lookup functionality which is needed - Add comment explaining why. - Add tests to ensure behavior remains correct. --- .../jvm/internal/DefaultJvmTestSuite.java | 19 +- .../JUnitCategoriesIntegrationSpec.groovy | 54 ++++- ...JUnitPlatformOptionsIntegrationSpec.groovy | 201 ++++++++++++++++++ .../integTest/java/org/gradle/CategoryA.java | 20 ++ .../integTest/java/org/gradle/CategoryB.java | 20 ++ .../java/org/gradle/SomeTestClass.java | 29 +++ .../build.gradle | 21 ++ .../java/org/gradle/SomeTestClass.java | 31 +++ .../test/java/org/gradle/SomeTestClass.java | 31 +++ 9 files changed, 415 insertions(+), 11 deletions(-) create mode 100644 subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec.groovy create mode 100644 subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/CategoryA.java create mode 100644 subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/CategoryB.java create mode 100644 subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/SomeTestClass.java create mode 100644 subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/build.gradle create mode 100644 subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java create mode 100644 subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java diff --git a/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java b/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java index f9a666ae14d2..7743dc745e89 100644 --- a/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java +++ b/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java @@ -26,6 +26,7 @@ import org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyAdder; import org.gradle.api.internal.tasks.AbstractTaskDependency; import org.gradle.api.internal.tasks.TaskDependencyResolveContext; +import org.gradle.api.internal.tasks.testing.TestFramework; import org.gradle.api.internal.tasks.testing.filter.DefaultTestFilter; import org.gradle.api.internal.tasks.testing.junit.JUnitTestFramework; import org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestFramework; @@ -45,6 +46,8 @@ import javax.annotation.Nullable; import javax.inject.Inject; +import java.util.HashMap; +import java.util.Map; public abstract class DefaultJvmTestSuite implements JvmTestSuite { public enum Frameworks { @@ -146,21 +149,27 @@ public DefaultJvmTestSuite(String name, DependencyFactory dependencyFactory, Con addDefaultTestTarget(); - // The values here can now be considered finalized upon the user setting them (see the org.gradle.api.tasks.testing.Test#testFramework(Closure) method). So - // there is now no need to use a map to ensure a given test framework is only created once. + // We can still execute this innermost provider lambda below used as the convention multiple times. + // So make sure, within a Test Suite, that we always return the same framework instance via computeIfAbsent() against this map. + // Doing so will ensure the UP-TO-DATE checking (tested in JUnitCategoriesIntegrationSpec, for instance) still works. + // + // You might think you can replace the map and just return a new instance (perhaps adding equals/hashCode implementations + // to the framework and options classes, but you cannot - tests should enforce this. + final Map frameworkLookup = new HashMap<>(3); + this.targets.withType(JvmTestSuiteTarget.class).configureEach(target -> { target.getTestTask().configure(task -> { task.getTestFrameworkProperty().convention(getVersionedTestingFramework().map(vtf -> { switch(vtf.type) { case NONE: // fall-through case JUNIT4: - return new JUnitTestFramework(task, (DefaultTestFilter) task.getFilter()); + return frameworkLookup.computeIfAbsent(vtf.type, f -> new JUnitTestFramework(task, (DefaultTestFilter) task.getFilter())); case KOTLIN_TEST: // fall-through case JUNIT_JUPITER: // fall-through case SPOCK: - return new JUnitPlatformTestFramework((DefaultTestFilter) task.getFilter()); + return frameworkLookup.computeIfAbsent(vtf.type, f -> new JUnitPlatformTestFramework((DefaultTestFilter) task.getFilter())); case TESTNG: - return new TestNGTestFramework(task, task.getClasspath(), (DefaultTestFilter) task.getFilter(), getObjectFactory()); + return frameworkLookup.computeIfAbsent(vtf.type, f -> new TestNGTestFramework(task, task.getClasspath(), (DefaultTestFilter) task.getFilter(), getObjectFactory())); default: throw new IllegalStateException("do not know how to handle " + vtf); } diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy index a6b2c2cca98c..42715ee1e6c4 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy @@ -115,13 +115,13 @@ public class MyTest { } @Issue('https://github.com/gradle/gradle/issues/4924') - def "re-executes test when #type is changed"() { + def "re-executes test when #type is changed in #suiteName"() { given: resources.maybeCopy("JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged") buildFile << """ |testing { | suites { - | test { + | $suiteDeclaration { | useJUnit() | targets { | all { @@ -137,17 +137,17 @@ public class MyTest { |}""".stripMargin() when: - succeeds ':test' + succeeds ":$task" then: - executedAndNotSkipped ':test' + executedAndNotSkipped ":$task" when: resources.maybeCopy("JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged") buildFile << """ |testing { | suites { - | test { + | $suiteDeclaration { | useJUnit() | targets { | all { @@ -163,12 +163,54 @@ public class MyTest { |}""".stripMargin() and: + succeeds ":$task" + + then: + executedAndNotSkipped ":$task" + + where: + suiteName | suiteDeclaration | task | type + 'test' | 'test' | 'test' | 'includeCategories' + 'test' | 'test' | 'test' | 'excludeCategories' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeCategories' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeCategories' + } + + @Issue('https://github.com/gradle/gradle/issues/4924') + def "skips test on re-run when #type is NOT changed"() { + given: + resources.maybeCopy("JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged") + buildFile << """ + |testing { + | suites { + | test { + | useJUnit() + | targets { + | all { + | testTask.configure { + | options { + | ${type} 'org.gradle.CategoryA' + | } + | } + | } + | } + | } + | } + |}""".stripMargin() + + when: succeeds ':test' then: executedAndNotSkipped ':test' + when: + succeeds ':test' + + then: + skipped ':test' + where: - type << ['includeCategories', 'excludeCategories'] + type << ['includeCategories'] } } diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec.groovy new file mode 100644 index 000000000000..047e5ab3d4f6 --- /dev/null +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec.groovy @@ -0,0 +1,201 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.testing.junitplatform; + +import org.gradle.integtests.fixtures.AbstractSampleIntegrationTest +import org.gradle.integtests.fixtures.TestResources +import org.junit.Rule + +class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest { + @Rule + TestResources resources = new TestResources(temporaryFolder) + + def "re-executes test when #type is changed in #suiteName"() { + given: + resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + buildFile << """ + |testing { + | suites { + | $suiteDeclaration { + | useJUnitJupiter() + | targets { + | all { + | testTask.configure { + | options { + | ${type} 'fast' + | } + | } + | } + | } + | } + | } + |}""".stripMargin() + + when: + succeeds ":$task" + + then: + executedAndNotSkipped ":$task" + + when: + resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + buildFile << """ + |testing { + | suites { + | $suiteDeclaration { + | useJUnitJupiter() + | targets { + | all { + | testTask.configure { + | options { + | ${type} 'slow' + | } + | } + | } + | } + | } + | } + |}""".stripMargin() + + and: + succeeds ":$task" + + then: + executedAndNotSkipped ":$task" + + where: + suiteName | suiteDeclaration | task | type + 'test' | 'test' | 'test' | 'includeTags' + 'test' | 'test' | 'test' | 'excludeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' + } + + def "can set non-options test property for test task in #suiteName prior to calling useJUnitJupiter()"() { + given: + resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + buildFile << """ + |testing { + | suites { + | $suiteDeclaration { + | targets { + | all { + | testTask.configure { + | minHeapSize = "128m" + | } + | } + | } + | useJUnitJupiter() + | targets { + | all { + | testTask.configure { + | options { + | ${type} 'fast' + | } + | } + | } + | } + | } + | } + |}""".stripMargin() + + when: + succeeds ":$task" + + then: + executedAndNotSkipped ":$task" + + where: + suiteName | suiteDeclaration | task | type + 'test' | 'test' | 'test' | 'includeTags' + 'test' | 'test' | 'test' | 'excludeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' + } + + def "can set options in #suiteName lexically prior to calling useJUnitJupiter()"() { + given: + resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + buildFile << """ + |testing { + | suites { + | $suiteDeclaration { + | targets { + | all { + | testTask.configure { + | options { + | ${type} 'fast' + | } + | } + | } + | } + | useJUnitJupiter() + | } + | } + |}""".stripMargin() + + when: + succeeds ":$task" + + then: + executedAndNotSkipped ":$task" + + where: + suiteName | suiteDeclaration | task | type + 'test' | 'test' | 'test' | 'includeTags' + 'test' | 'test' | 'test' | 'excludeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' + } + + def "can set options on test task directly, outside of default test suite, prior to calling useJUnitJupiter()"() { + given: + resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + buildFile << """ + |test { + | options { + | includeCategories 'org.gradle.CategoryA' + | } + |} + | + |testing { + | suites { + | test { + | useJUnitJupiter() + | targets { + | all { + | testTask.configure { + | options { + | ${type} 'fast' + | } + | } + | } + | } + | } + | } + |}""".stripMargin() + + when: + succeeds ":test" + + then: + executedAndNotSkipped ":test" + + where: + type << ['includeTags', 'excludeTags'] + } +} diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/CategoryA.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/CategoryA.java new file mode 100644 index 000000000000..8329eaec152a --- /dev/null +++ b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/CategoryA.java @@ -0,0 +1,20 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle; + +public interface CategoryA { +} diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/CategoryB.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/CategoryB.java new file mode 100644 index 000000000000..4c09973ad3ea --- /dev/null +++ b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/CategoryB.java @@ -0,0 +1,20 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle; + +public interface CategoryB { +} diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/SomeTestClass.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/SomeTestClass.java new file mode 100644 index 000000000000..c60f95962337 --- /dev/null +++ b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec/reExecutesWhenPropertyIsChanged/src/integTest/java/org/gradle/SomeTestClass.java @@ -0,0 +1,29 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle; + +import org.junit.Test; + +public class SomeTestClass { + @Test + public void ok1() { + } + + @Test + public void ok2() { + } +} diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/build.gradle b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/build.gradle new file mode 100644 index 000000000000..77acb152a3a2 --- /dev/null +++ b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/build.gradle @@ -0,0 +1,21 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +apply plugin: "java" + +repositories { + mavenCentral() +} diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java new file mode 100644 index 000000000000..5428069719fc --- /dev/null +++ b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java @@ -0,0 +1,31 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Tag; + +@Tag("fast") +public class SomeTestClass { + @Test + public void ok1() { + } + + @Test + public void ok2() { + } +} diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java new file mode 100644 index 000000000000..5428069719fc --- /dev/null +++ b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java @@ -0,0 +1,31 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Tag; + +@Tag("fast") +public class SomeTestClass { + @Test + public void ok1() { + } + + @Test + public void ok2() { + } +} From 2ec207e06598f7af4a4a789fbbed6b1b5611a3fa Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Tue, 13 Sep 2022 12:33:26 -0400 Subject: [PATCH 08/17] Remove unused field --- .../src/main/java/org/gradle/api/tasks/testing/Test.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java index fc6189f35ab4..ba2d7ac3506f 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java @@ -173,12 +173,6 @@ public class Test extends AbstractTestTask implements JavaForkOptions, PatternFi private final ConfigurableFileCollection stableClasspath; private final Property testFramework; - /* - * These fields are status variables that are used to keep track of the state of the test task - * to prevent potential errors or unexpected behavior caused by setting the test framework - * after setting options. - */ - private boolean userHasConfiguredTestFramework; private boolean optionsAccessed; private boolean scanForTestClasses = true; @@ -978,7 +972,6 @@ private TestFramework useTestFramework(TestFram oldFramework.getDisplayName())); } - userHasConfiguredTestFramework = true; this.testFramework.set(testFramework); if (testFrameworkConfigure != null) { From 3be7020bcd78eb26ddea0de4f2432c362c2d60a1 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Tue, 13 Sep 2022 16:47:23 -0400 Subject: [PATCH 09/17] Expose a property from the Test task to check if options are already accessed; check this when changing framework in a suite - We need to check not just when changing the test framework within a test task, but when changing the test framework for a suite if the associated test tasks for that suite have had options accessed. Otherwise, the test task will silently continue to use the options and framework first configured without switching to the new ones. - Create new test class to demonstrate misconfigurations of options. --- .../3c3e47be-b5ed-426a-8b9f-cfa00d3b09db | 20 +- .../provider-task-file-collection.txt | 24 +- .../provider-task-properties.txt | 95 ++++---- .../archunit_store/provider-text-resource.txt | 4 +- .../public-api-mutable-file-collection.txt | 2 +- .../public-api-mutable-properties.txt | 22 +- .../public-api-mutable-text-resource.txt | 2 +- .../jvm/internal/DefaultJvmTestSuite.java | 11 + ...oovy => TestOptionsIntegrationSpec.groovy} | 205 ++++++++++++++---- .../build.gradle | 0 .../java/org/gradle/SomeTestClass.java | 0 .../test/java/org/gradle/SomeTestClass.java | 0 .../org/gradle/api/tasks/testing/Test.java | 12 + 13 files changed, 268 insertions(+), 129 deletions(-) rename subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/{junitplatform/JUnitPlatformOptionsIntegrationSpec.groovy => TestOptionsIntegrationSpec.groovy} (51%) rename subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/{junitplatform/JUnitPlatformOptionsIntegrationSpec => TestOptionsIntegrationSpec}/build.gradle (100%) rename subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/{junitplatform/JUnitPlatformOptionsIntegrationSpec => TestOptionsIntegrationSpec}/src/integTest/java/org/gradle/SomeTestClass.java (100%) rename subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/{junitplatform/JUnitPlatformOptionsIntegrationSpec => TestOptionsIntegrationSpec}/src/test/java/org/gradle/SomeTestClass.java (100%) diff --git a/subprojects/architecture-test/src/changes/archunit_store/3c3e47be-b5ed-426a-8b9f-cfa00d3b09db b/subprojects/architecture-test/src/changes/archunit_store/3c3e47be-b5ed-426a-8b9f-cfa00d3b09db index a76925e4c6b1..791e78a6f7d6 100644 --- a/subprojects/architecture-test/src/changes/archunit_store/3c3e47be-b5ed-426a-8b9f-cfa00d3b09db +++ b/subprojects/architecture-test/src/changes/archunit_store/3c3e47be-b5ed-426a-8b9f-cfa00d3b09db @@ -5,7 +5,7 @@ Method has arguments/return t Method has arguments/return type org.gradle.internal.Factory that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (ExclusiveContentRepository.java:0) Method has arguments/return type org.gradle.internal.metaobject.DynamicObject that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Convention.java:0) Method has arguments/return type org.gradle.api.internal.project.ProjectInternal that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (JavaPluginConvention.java:0) -Method has arguments/return type org.gradle.api.internal.project.IsolatedAntBuilder that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Checkstyle.java:123) +Method has arguments/return type org.gradle.api.internal.project.IsolatedAntBuilder that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Checkstyle.java:122) Method has arguments/return type org.gradle.api.internal.project.IsolatedAntBuilder that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (CodeNarc.java:127) Method has arguments/return type org.gradle.api.internal.project.IsolatedAntBuilder that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Pmd.java:117) Method has arguments/return type org.gradle.api.internal.attributes.ImmutableAttributes that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (GenerateMavenPom.java:65) @@ -25,12 +25,12 @@ Method has a Method has arguments/return type org.gradle.api.tasks.diagnostics.internal.PropertyReportRenderer that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (PropertyReportTask.java:67) Method has arguments/return type org.gradle.api.tasks.diagnostics.internal.ReportRenderer that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (TaskReportTask.java:69) Method has arguments/return type org.gradle.api.tasks.diagnostics.internal.TaskReportRenderer that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (TaskReportTask.java:76) -Method has arguments/return type org.gradle.api.internal.tasks.AntGroovydoc that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Groovydoc.java:199) -Method has arguments/return type org.gradle.api.internal.tasks.AntGroovydoc that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Groovydoc.java:208) +Method has arguments/return type org.gradle.api.internal.tasks.AntGroovydoc that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Groovydoc.java:198) +Method has arguments/return type org.gradle.api.internal.tasks.AntGroovydoc that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Groovydoc.java:207) Method has arguments/return type org.gradle.language.base.internal.compile.Compiler that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (ScalaCompile.java:123) -Method has arguments/return type org.gradle.api.internal.tasks.testing.TestFramework that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Test.java:915) -Method has arguments/return type org.gradle.api.internal.tasks.testing.TestFramework that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Test.java:910) -Method has arguments/return type org.gradle.api.internal.tasks.testing.TestFramework that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Test.java:919) +Method has arguments/return type org.gradle.api.internal.tasks.testing.TestFramework that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Test.java:916) +Method has arguments/return type org.gradle.api.internal.tasks.testing.TestFramework that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Test.java:911) +Method has arguments/return type org.gradle.api.internal.tasks.testing.TestFramework that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Test.java:920) Method has arguments/return type org.gradle.buildinit.plugins.internal.ProjectLayoutSetupRegistry that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (InitBuild.java:177) Method has arguments/return type org.gradle.external.javadoc.internal.JavadocOptionFileWriterContext that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (OptionLessJavadocOptionFileOption.java:0) Method has arguments/return type org.gradle.internal.operations.logging.BuildOperationLoggerFactory that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (Assemble.java:85) @@ -67,7 +67,7 @@ Method h Method has arguments/return type org.bouncycastle.openpgp.PGPSignatureGenerator that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (PgpSignatory.java:106) Method has arguments/return type org.bouncycastle.openpgp.PGPSecretKey that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (PgpSignatoryFactory.java:73) Method has arguments/return type org.bouncycastle.openpgp.PGPSecretKey that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (PgpSignatoryFactory.java:121) -Method has arguments/return type org.gradle.internal.Pair that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (CollectionUtils.java:590) -Method has arguments/return type org.gradle.internal.metaobject.ConfigureDelegate that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (ConfigureUtil.java:179) -Method has arguments/return type java.util.zip.Checksum that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (GFileUtils.java:279) -Method has arguments/return type org.gradle.internal.Factory that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (GUtil.java:176) \ No newline at end of file +Method has arguments/return type org.gradle.internal.Pair that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (CollectionUtils.java:656) +Method has arguments/return type org.gradle.internal.metaobject.ConfigureDelegate that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (ConfigureUtil.java:192) +Method has arguments/return type java.util.zip.Checksum that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (GFileUtils.java:329) +Method has arguments/return type org.gradle.internal.Factory that is not Gradle public API or primitive or built-in JDK classes or Groovy classes in (GUtil.java:195) \ No newline at end of file diff --git a/subprojects/architecture-test/src/changes/archunit_store/provider-task-file-collection.txt b/subprojects/architecture-test/src/changes/archunit_store/provider-task-file-collection.txt index d2217938e9a6..f9d38014a412 100644 --- a/subprojects/architecture-test/src/changes/archunit_store/provider-task-file-collection.txt +++ b/subprojects/architecture-test/src/changes/archunit_store/provider-task-file-collection.txt @@ -1,8 +1,8 @@ Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (AntlrTask.java:181) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (AntlrTask.java:298) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Checkstyle.java:246) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Checkstyle.java:261) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Checkstyle.java:238) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Checkstyle.java:244) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Checkstyle.java:259) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Checkstyle.java:236) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (CodeNarc.java:192) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (CodeNarc.java:209) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (CodeNarc.java:104) @@ -19,12 +19,12 @@ Method does not ha Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (GroovyCompile.java:114) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (GroovyCompile.java:389) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (GroovyCompile.java:358) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (JavaCompile.java:403) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (JavaCompile.java:405) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (JavaCompile.java:120) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (DependencyInsightReportTask.java:201) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Groovydoc.java:187) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Groovydoc.java:170) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Groovydoc.java:143) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (DependencyInsightReportTask.java:200) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Groovydoc.java:186) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Groovydoc.java:169) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Groovydoc.java:142) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Javadoc.java:336) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Javadoc.java:229) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (ScalaCompile.java:70) @@ -33,11 +33,11 @@ Method does not hav Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (ScalaDoc.java:151) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (ScalaDoc.java:163) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (ScalaDoc.java:113) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Test.java:355) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Test.java:1124) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Test.java:823) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Test.java:356) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Test.java:1108) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (Test.java:824) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (GenerateXcodeWorkspaceFileTask.java:60) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (CreateStartScripts.java:320) -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (AbstractScalaCompile.java:280) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (AbstractScalaCompile.java:279) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (InstallExecutable.java:164) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (JacocoBase.java:36) \ No newline at end of file diff --git a/subprojects/architecture-test/src/changes/archunit_store/provider-task-properties.txt b/subprojects/architecture-test/src/changes/archunit_store/provider-task-properties.txt index 114b7948e5ba..c99933f03262 100644 --- a/subprojects/architecture-test/src/changes/archunit_store/provider-task-properties.txt +++ b/subprojects/architecture-test/src/changes/archunit_store/provider-task-properties.txt @@ -5,15 +5,15 @@ Method does not have raw retu Method does not have raw return type assignable to org.gradle.api.provider.Property in (AntlrTask.java:95) Method does not have raw return type assignable to org.gradle.api.provider.Property in (AntlrTask.java:107) Method does not have raw return type assignable to org.gradle.api.provider.Property in (AntlrTask.java:119) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:100) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:297) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:338) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:368) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:390) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Checkstyle.java:328) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Checkstyle.java:63) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:348) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:410) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:99) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:295) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:336) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:366) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:388) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Checkstyle.java:326) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Checkstyle.java:62) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:346) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Checkstyle.java:408) Method does not have raw return type assignable to org.gradle.api.provider.Property in (CodeNarc.java:95) Method does not have raw return type assignable to org.gradle.api.provider.Property in (CodeNarc.java:299) Method does not have raw return type assignable to org.gradle.api.provider.Property in (CodeNarc.java:245) @@ -137,8 +137,8 @@ Method d Method does not have raw return type assignable to org.gradle.api.provider.Property in (AbstractCompile.java:164) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (GroovyCompile.java:369) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (GroovyCompile.java:379) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (JavaCompile.java:386) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (JavaCompile.java:396) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (JavaCompile.java:388) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (JavaCompile.java:398) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (AbstractConfigurationReportTask.java:51) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (AbstractConfigurationReportTask.java:73) Method does not have raw return type assignable to org.gradle.api.provider.Property in (AbstractDependencyReportTask.java:111) @@ -148,24 +148,24 @@ Method doe Method does not have raw return type assignable to org.gradle.api.provider.Property in (AbstractReportTask.java:140) Method does not have raw return type assignable to org.gradle.api.provider.Property in (ConventionReportTask.java:88) Method does not have raw return type assignable to org.gradle.api.provider.Property in (ConventionReportTask.java:109) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (DependencyInsightReportTask.java:167) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (DependencyInsightReportTask.java:233) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (DependencyInsightReportTask.java:166) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (DependencyInsightReportTask.java:232) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (DependencyReportTask.java:30) Method does not have raw return type assignable to org.gradle.api.provider.Property in (PropertyReportTask.java:63) Method does not have raw return type assignable to org.gradle.api.provider.Property in (TaskReportTask.java:114) Method does not have raw return type assignable to org.gradle.api.provider.Property in (TaskReportTask.java:142) Method does not have raw return type assignable to org.gradle.api.provider.Property in (TaskReportTask.java:69) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (TaskReportTask.java:92) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:199) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:153) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:282) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:320) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:301) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:443) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:263) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:231) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:246) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:216) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:198) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:152) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:281) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:319) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:300) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:400) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:262) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:230) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:245) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Groovydoc.java:215) Method does not have raw return type assignable to org.gradle.api.provider.Property in (Javadoc.java:251) Method does not have raw return type assignable to org.gradle.api.provider.Property in (Javadoc.java:416) Method does not have raw return type assignable to org.gradle.api.provider.Property in (Javadoc.java:276) @@ -185,29 +185,30 @@ Method does Method does not have raw return type assignable to org.gradle.api.provider.Provider in (AbstractTestTask.java:102) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (AbstractTestTask.java:571) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (AbstractTestTask.java:368) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:547) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:494) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:512) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:388) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:478) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:572) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:887) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:288) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:539) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:1160) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:864) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:279) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:428) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:436) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:412) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:1194) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:380) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:632) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:958) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:321) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:915) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:243) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:1137) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:548) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:495) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:513) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:389) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:479) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:573) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:888) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:289) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:540) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:1144) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:865) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:280) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:429) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:437) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:413) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:1178) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:381) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:633) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:934) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:971) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:322) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Test.java:916) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:244) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (Test.java:1121) Method does not have raw return type assignable to org.gradle.api.provider.Property in (Wrapper.java:426) Method does not have raw return type assignable to org.gradle.api.provider.Property in (Wrapper.java:409) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (Wrapper.java:309) @@ -244,7 +245,7 @@ Method does not have raw return type assignable to org.gradle.api.provider.Provider in (GenerateSolutionFileTask.java:57) Method does not have raw return type assignable to org.gradle.api.provider.Property in (GenerateSchemeFileTask.java:128) Method does not have raw return type assignable to org.gradle.api.provider.Property in (GenerateSchemeFileTask.java:51) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (GenerateXcodeProjectFileTask.java:317) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (GenerateXcodeProjectFileTask.java:319) Method does not have raw return type assignable to org.gradle.api.provider.Property in (GenerateXcodeWorkspaceFileTask.java:69) Method does not have raw return type assignable to org.gradle.api.provider.Property in (CreateStartScripts.java:298) Method does not have raw return type assignable to org.gradle.api.provider.Property in (CreateStartScripts.java:285) diff --git a/subprojects/architecture-test/src/changes/archunit_store/provider-text-resource.txt b/subprojects/architecture-test/src/changes/archunit_store/provider-text-resource.txt index 419a2a67dd16..821301e4b0f5 100644 --- a/subprojects/architecture-test/src/changes/archunit_store/provider-text-resource.txt +++ b/subprojects/architecture-test/src/changes/archunit_store/provider-text-resource.txt @@ -1,4 +1,4 @@ -Method has raw return type org.gradle.api.resources.TextResource in (Checkstyle.java:278) +Method has raw return type org.gradle.api.resources.TextResource in (Checkstyle.java:276) Method has raw return type org.gradle.api.resources.TextResource in (CodeNarc.java:228) Method has raw return type org.gradle.api.resources.TextResource in (Pmd.java:304) -Method has raw return type org.gradle.api.resources.TextResource in (Groovydoc.java:339) \ No newline at end of file +Method has raw return type org.gradle.api.resources.TextResource in (Groovydoc.java:338) \ No newline at end of file diff --git a/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-file-collection.txt b/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-file-collection.txt index 57c52d54020c..26273057a702 100644 --- a/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-file-collection.txt +++ b/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-file-collection.txt @@ -1,4 +1,4 @@ -Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (PmdExtension.java:185) +Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (PmdExtension.java:184) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (SourceSet.java:0) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (SourceSet.java:0) Method does not have raw return type assignable to org.gradle.api.file.ConfigurableFileCollection in (SourceSet.java:0) diff --git a/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-properties.txt b/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-properties.txt index ab035b3b2072..19dc4408f766 100644 --- a/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-properties.txt +++ b/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-properties.txt @@ -189,9 +189,9 @@ Method doe Method does not have raw return type assignable to org.gradle.api.provider.Property in (CodeQualityExtension.java:51) Method does not have raw return type assignable to org.gradle.api.provider.Property in (CodeQualityExtension.java:37) Method does not have raw return type assignable to org.gradle.api.provider.Property in (CodeQualityExtension.java:67) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (PmdExtension.java:64) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (PmdExtension.java:95) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (PmdExtension.java:217) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (PmdExtension.java:63) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (PmdExtension.java:94) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (PmdExtension.java:216) Method does not have raw return type assignable to org.gradle.api.provider.Property in (IvyArtifact.java:0) Method does not have raw return type assignable to org.gradle.api.provider.Property in (IvyArtifact.java:0) Method does not have raw return type assignable to org.gradle.api.provider.Property in (IvyArtifact.java:0) @@ -352,11 +352,11 @@ Method does no Method does not have raw return type assignable to org.gradle.api.provider.Property in (AbstractBuildCache.java:49) Method does not have raw return type assignable to org.gradle.api.provider.Property in (BuildCache.java:0) Method does not have raw return type assignable to org.gradle.api.provider.Property in (BuildCache.java:0) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (HttpBuildCache.java:98) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCache.java:70) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCache.java:155) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCache.java:124) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCache.java:196) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (HttpBuildCache.java:97) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCache.java:69) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCache.java:154) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCache.java:123) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCache.java:193) Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCacheCredentials.java:61) Method does not have raw return type assignable to org.gradle.api.provider.Property in (HttpBuildCacheCredentials.java:40) Method does not have raw return type assignable to org.gradle.api.provider.Property in (DirectoryBuildCache.java:38) @@ -636,8 +636,8 @@ Method does not have raw return type assignable to org.gradle.api.provider.Property in (EclipseWtpComponent.java:290) Method does not have raw return type assignable to org.gradle.api.provider.Property in (EclipseWtpComponent.java:219) Method does not have raw return type assignable to org.gradle.api.provider.Property in (EclipseWtpComponent.java:206) -Method does not have raw return type assignable to org.gradle.api.provider.Property in (EclipseWtpFacet.java:129) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (EclipseWtpFacet.java:94) +Method does not have raw return type assignable to org.gradle.api.provider.Property in (EclipseWtpFacet.java:131) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (EclipseWtpFacet.java:96) Method does not have raw return type assignable to org.gradle.api.provider.Property in (Facet.java:77) Method does not have raw return type assignable to org.gradle.api.provider.Property in (Facet.java:69) Method does not have raw return type assignable to org.gradle.api.provider.Property in (Facet.java:85) @@ -858,7 +858,7 @@ Method does not have raw return type assignable to org.gradle.api.provider.Provider in (UnexpectedBuildResultException.java:40) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (ListenerFailedException.java:39) Method does not have raw return type assignable to org.gradle.api.provider.Property in (EclipseRuntime.java:0) -Method does not have raw return type assignable to org.gradle.api.provider.Provider in (ConfigureUtil.java:121) +Method does not have raw return type assignable to org.gradle.api.provider.Provider in (ConfigureUtil.java:130) Method does not have raw return type assignable to org.gradle.api.provider.Property in (VersionControlRepository.java:0) Method does not have raw return type assignable to org.gradle.api.provider.Provider in (VersionControlSpec.java:0) Method does not have raw return type assignable to org.gradle.api.provider.Property in (VersionControlSpec.java:0) diff --git a/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-text-resource.txt b/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-text-resource.txt index 0eec6a286d0d..6a9edcc0e25e 100644 --- a/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-text-resource.txt +++ b/subprojects/architecture-test/src/changes/archunit_store/public-api-mutable-text-resource.txt @@ -1,5 +1,5 @@ Method has raw return type org.gradle.api.resources.TextResource in (CheckstyleExtension.java:67) Method has raw return type org.gradle.api.resources.TextResource in (CodeNarcExtension.java:53) -Method has raw return type org.gradle.api.resources.TextResource in (PmdExtension.java:158) +Method has raw return type org.gradle.api.resources.TextResource in (PmdExtension.java:157) Method has raw return type org.gradle.api.resources.TextResource in (CustomizableHtmlReport.java:0) Method has raw return type org.gradle.api.resources.TextResource in (TemplateBasedScriptGenerator.java:0) \ No newline at end of file diff --git a/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java b/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java index 7743dc745e89..2327e490571e 100644 --- a/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java +++ b/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java @@ -19,6 +19,7 @@ import com.google.common.base.Preconditions; import org.gradle.api.Action; import org.gradle.api.ExtensiblePolymorphicDomainObjectContainer; +import org.gradle.api.GradleException; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ConfigurationContainer; import org.gradle.api.artifacts.dsl.DependencyAdder; @@ -305,6 +306,16 @@ public void useTestNG(Provider version) { } private void setFrameworkTo(Frameworks framework, Provider versionProvider) { + this.targets.withType(JvmTestSuiteTarget.class).configureEach(target -> { + target.getTestTask().configure(task -> { + if (task.getOptionsAccessed()) { + throw new GradleException(String.format("You cannot set the test framework on suite: %s after accessing test options on an associated Test task: %s.", + getName(), + task.getName())); + } + }); + }); + getVersionedTestingFramework().set(versionProvider.map(v -> new VersionedTestingFramework(framework, v))); attachDependencyAction.execute(null); } diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy similarity index 51% rename from subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec.groovy rename to subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy index 047e5ab3d4f6..7d56bc2878b3 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy @@ -14,30 +14,34 @@ * limitations under the License. */ -package org.gradle.testing.junitplatform; +package org.gradle.testing; import org.gradle.integtests.fixtures.AbstractSampleIntegrationTest import org.gradle.integtests.fixtures.TestResources import org.junit.Rule -class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest { +/** + * These tests demonstrate what is and isn't allowed in terms of modifying the {@link org.gradle.api.tasks.testing.TestFrameworkOptions TestFrameworkOptions} + * provided to a {@link org.gradle.api.tasks.testing.Test Test} task. + */ +class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { @Rule TestResources resources = new TestResources(temporaryFolder) - def "re-executes test when #type is changed in #suiteName"() { + def "can NOT set options and then change framework within a suite using a single task configuration action"() { given: - resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ |testing { | suites { - | $suiteDeclaration { - | useJUnitJupiter() + | test { | targets { | all { | testTask.configure { | options { - | ${type} 'fast' + | includeCategories 'org.gradle.CategoryA' | } + | useJUnitPlatform() | } | } | } @@ -46,48 +50,45 @@ class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest |}""".stripMargin() when: - succeeds ":$task" + fails ":test" then: - executedAndNotSkipped ":$task" + result.assertHasErrorOutput("You cannot change the test framework to: JUnit Platform after accessing test options. The current framework is: JUnit 4.") + } - when: - resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + def "can NOT set options and then change framework within a suite using 2 different task configuration actions"() { + given: + resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ |testing { | suites { - | $suiteDeclaration { - | useJUnitJupiter() + | test { | targets { | all { | testTask.configure { | options { - | ${type} 'slow' + | includeCategories 'org.gradle.CategoryA' | } | } + | testTask.configure { + | useJUnitPlatform() + | } | } | } | } | } |}""".stripMargin() - and: - succeeds ":$task" + when: + fails ":test" then: - executedAndNotSkipped ":$task" - - where: - suiteName | suiteDeclaration | task | type - 'test' | 'test' | 'test' | 'includeTags' - 'test' | 'test' | 'test' | 'excludeTags' - 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' - 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' + result.assertHasErrorOutput("You cannot change the test framework to: JUnit Platform after accessing test options. The current framework is: JUnit 4.") } - def "can set non-options test property for test task in #suiteName prior to calling useJUnitJupiter()"() { + def "can NOT set options in #suiteName prior to calling useJUnitJupiter() on suite"() { given: - resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ |testing { | suites { @@ -95,29 +96,22 @@ class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest | targets { | all { | testTask.configure { - | minHeapSize = "128m" - | } - | } - | } - | useJUnitJupiter() - | targets { - | all { - | testTask.configure { | options { | ${type} 'fast' | } | } | } | } + | useJUnitJupiter() | } | } |}""".stripMargin() when: - succeeds ":$task" + fails ":$task" then: - executedAndNotSkipped ":$task" + result.assertHasErrorOutput("You cannot set the test framework on suite: $suiteName after accessing test options on an associated Test task: $task.") where: suiteName | suiteDeclaration | task | type @@ -127,9 +121,9 @@ class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' } - def "can set options in #suiteName lexically prior to calling useJUnitJupiter()"() { + def "can NOT set options in #suiteName prior to calling useJUnitJupiter() on suite across 2 configurations actions"() { given: - resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ |testing { | suites { @@ -143,16 +137,22 @@ class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest | } | } | } + | } + | } + |} + |testing { + | suites { + | $suiteDeclaration { | useJUnitJupiter() | } | } |}""".stripMargin() when: - succeeds ":$task" + fails ":$task" then: - executedAndNotSkipped ":$task" + result.assertHasErrorOutput("You cannot set the test framework on suite: $suiteName after accessing test options on an associated Test task: $task.") where: suiteName | suiteDeclaration | task | type @@ -162,9 +162,9 @@ class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' } - def "can set options on test task directly, outside of default test suite, prior to calling useJUnitJupiter()"() { + def "can NOT set options on test task directly outside of default test suite, prior to setting test framework inside of suite"() { given: - resources.maybeCopy("JUnitPlatformOptionsIntegrationSpec") + resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ |test { | options { @@ -176,6 +176,91 @@ class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest | suites { | test { | useJUnitJupiter() + | } + | } + |}""".stripMargin() + + when: + fails ":test" + + then: + result.assertHasErrorOutput("You cannot set the test framework on suite: test after accessing test options on an associated Test task: test.") + } + + def "can NOT set options on test task directly, outside of default test suite, then again inside suite"() { + given: + resources.maybeCopy("TestOptionsIntegrationSpec") + buildFile << """ + |test { + | useJUnitPlatform() + | options { + | includeTags 'fast' + | } + |} + | + |testing { + | suites { + | test { + | useJUnit() // NOT ALLOWED, task is already configured with a framework, should fail-fast here + | } + | } + |}""".stripMargin() + + when: + fails ":test" + + then: + result.assertHasErrorOutput("You cannot set the test framework on suite: test after accessing test options on an associated Test task: test.") + } + + def "can set non-options test property for test task in #suiteName prior to setting framework within suite"() { + given: + resources.maybeCopy("TestOptionsIntegrationSpec") + buildFile << """ + |testing { + | suites { + | $suiteDeclaration { + | targets { + | all { + | testTask.configure { + | minHeapSize = "128m" + | } + | } + | } + | useJUnitJupiter() + | targets { + | all { + | testTask.configure { + | options { + | ${type} 'fast' + | } + | } + | } + | } + | } + | } + |}""".stripMargin() + + expect: + succeeds ":$task" + + where: + suiteName | suiteDeclaration | task | type + 'test' | 'test' | 'test' | 'includeTags' + 'test' | 'test' | 'test' | 'excludeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' + } + + // See JUnitCategoriesIntegrationSpec for the inspiration for this test + def "re-executes test when #type is changed in #suiteName"() { + given: + resources.maybeCopy("TestOptionsIntegrationSpec") + buildFile << """ + |testing { + | suites { + | $suiteDeclaration { + | useJUnitJupiter() | targets { | all { | testTask.configure { @@ -190,12 +275,42 @@ class JUnitPlatformOptionsIntegrationSpec extends AbstractSampleIntegrationTest |}""".stripMargin() when: - succeeds ":test" + succeeds ":$task" then: - executedAndNotSkipped ":test" + executedAndNotSkipped ":$task" + + when: + resources.maybeCopy("TestOptionsIntegrationSpec") + buildFile << """ + |testing { + | suites { + | $suiteDeclaration { + | useJUnitJupiter() + | targets { + | all { + | testTask.configure { + | options { + | ${type} 'slow' + | } + | } + | } + | } + | } + | } + |}""".stripMargin() + + and: + succeeds ":$task" + + then: + executedAndNotSkipped ":$task" where: - type << ['includeTags', 'excludeTags'] + suiteName | suiteDeclaration | task | type + 'test' | 'test' | 'test' | 'includeTags' + 'test' | 'test' | 'test' | 'excludeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' } } diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/build.gradle b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/build.gradle similarity index 100% rename from subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/build.gradle rename to subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/build.gradle diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java similarity index 100% rename from subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java rename to subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java similarity index 100% rename from subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/junitplatform/JUnitPlatformOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java rename to subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java diff --git a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java index da493ece0cd1..7456b0a8139e 100644 --- a/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java +++ b/subprojects/testing-jvm/src/main/java/org/gradle/api/tasks/testing/Test.java @@ -959,6 +959,18 @@ public TestFrameworkOptions options(Action testFra return options; } + /** + * Checks if the options for this test task have already been accessed; if so the framework cannot be changed on either the + * task or it's associated test suite. + * + * @since 8.0 + */ + @Internal + @Incubating + public Boolean getOptionsAccessed() { + return optionsAccessed; + } + TestFramework useTestFramework(TestFramework testFramework) { return useTestFramework(testFramework, null); } From 86995a28a899a68e7b36b71053579dbff9672293 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 14 Sep 2022 07:43:31 -0400 Subject: [PATCH 10/17] Update test expectations now that reseting options fails fast - Consolidate options-related tests. --- .../testing/TestOptionsIntegrationSpec.groovy | 44 ++++++++++++++++++ .../TestSuitesIntegrationTest.groovy | 45 ------------------- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy index 7d56bc2878b3..8f05643be5ad 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy @@ -313,4 +313,48 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' } + + // Migrated from TestSuitesIntegrationTest to consolidate options-related tests + def "build fails when test framework is changed to another kind when realizing task and configuring options"() { + buildFile << """ + plugins { + id 'java' + } + + ${mavenCentralRepository()} + + testing { + suites { + integrationTest(JvmTestSuite) { + useJUnit() + targets.all { + // explicitly realize the task now to cause this configuration to run now + testTask.get().configure { + options { + excludeCategories "com.example.Exclude" + } + } + } + } + } + } + + testing { + suites { + integrationTest { + // This is ignored + useTestNG() + } + } + } + + check.dependsOn testing.suites + """ + + when: + fails("check") + + then: + result.assertHasErrorOutput("You cannot set the test framework on suite: integrationTest after accessing test options on an associated Test task: integrationTest.") + } } diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy index 27ed7f0ddb56..3b47364ccb1e 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy @@ -555,51 +555,6 @@ class TestSuitesIntegrationTest extends AbstractIntegrationSpec { failure.assertHasErrorOutput("You cannot change the test framework to: JUnit Platform after accessing test options. The current framework is: JUnit 4.") } - // This is not the behavior we want in the long term because this makes build configuration sensitive to the order - // that tasks are realized. - // useTestNG() is ignored here because we finalize the test framework on the task as soon as we configure options - // The test framework options should be pushed up into the test suite target/test suite and passed down into the - // Test task - def "build succeeds when test framework is changed to another kind when realizing task and configuring options"() { - buildFile << """ - plugins { - id 'java' - } - - ${mavenCentralRepository()} - - testing { - suites { - integrationTest(JvmTestSuite) { - useJUnit() - targets.all { - // explicitly realize the task now to cause this configuration to run now - testTask.get().configure { - options { - excludeCategories "com.example.Exclude" - } - } - } - } - } - } - - testing { - suites { - integrationTest { - // This is ignored - useTestNG() - } - } - } - - check.dependsOn testing.suites - """ - - expect: - succeeds("check") - } - @Issue("https://github.com/gradle/gradle/issues/18622") def "custom Test tasks eagerly realized prior to Java and Test Suite plugin application do not fail to be configured when combined with test suites"() { buildFile << """ From 2624e9b8cf4f68f735c214d3fa72e15801a25aec Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 14 Sep 2022 14:48:41 -0400 Subject: [PATCH 11/17] Clarify tests - Remove margin bar in multiline strings. - Make naming of migrated method consistent. - Remove extraneous comments. --- .../testing/TestOptionsIntegrationSpec.groovy | 312 +++++++++--------- 1 file changed, 155 insertions(+), 157 deletions(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy index 8f05643be5ad..7b94ff42d4ab 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy @@ -32,22 +32,22 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { given: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |testing { - | suites { - | test { - | targets { - | all { - | testTask.configure { - | options { - | includeCategories 'org.gradle.CategoryA' - | } - | useJUnitPlatform() - | } - | } - | } - | } - | } - |}""".stripMargin() + testing { + suites { + test { + targets { + all { + testTask.configure { + options { + includeCategories 'org.gradle.CategoryA' + } + useJUnitPlatform() + } + } + } + } + } + }""".stripMargin() when: fails ":test" @@ -60,24 +60,24 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { given: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |testing { - | suites { - | test { - | targets { - | all { - | testTask.configure { - | options { - | includeCategories 'org.gradle.CategoryA' - | } - | } - | testTask.configure { - | useJUnitPlatform() - | } - | } - | } - | } - | } - |}""".stripMargin() + testing { + suites { + test { + targets { + all { + testTask.configure { + options { + includeCategories 'org.gradle.CategoryA' + } + } + testTask.configure { + useJUnitPlatform() + } + } + } + } + } + }""".stripMargin() when: fails ":test" @@ -90,22 +90,22 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { given: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |testing { - | suites { - | $suiteDeclaration { - | targets { - | all { - | testTask.configure { - | options { - | ${type} 'fast' - | } - | } - | } - | } - | useJUnitJupiter() - | } - | } - |}""".stripMargin() + testing { + suites { + $suiteDeclaration { + targets { + all { + testTask.configure { + options { + ${type} 'fast' + } + } + } + } + useJUnitJupiter() + } + } + }""".stripMargin() when: fails ":$task" @@ -125,28 +125,28 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { given: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |testing { - | suites { - | $suiteDeclaration { - | targets { - | all { - | testTask.configure { - | options { - | ${type} 'fast' - | } - | } - | } - | } - | } - | } - |} - |testing { - | suites { - | $suiteDeclaration { - | useJUnitJupiter() - | } - | } - |}""".stripMargin() + testing { + suites { + $suiteDeclaration { + targets { + all { + testTask.configure { + options { + ${type} 'fast' + } + } + } + } + } + } + } + testing { + suites { + $suiteDeclaration { + useJUnitJupiter() + } + } + }""".stripMargin() when: fails ":$task" @@ -166,19 +166,19 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { given: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |test { - | options { - | includeCategories 'org.gradle.CategoryA' - | } - |} - | - |testing { - | suites { - | test { - | useJUnitJupiter() - | } - | } - |}""".stripMargin() + test { + options { + includeCategories 'org.gradle.CategoryA' + } + } + + testing { + suites { + test { + useJUnitJupiter() + } + } + }""".stripMargin() when: fails ":test" @@ -191,20 +191,20 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { given: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |test { - | useJUnitPlatform() - | options { - | includeTags 'fast' - | } - |} - | - |testing { - | suites { - | test { - | useJUnit() // NOT ALLOWED, task is already configured with a framework, should fail-fast here - | } - | } - |}""".stripMargin() + test { + useJUnitPlatform() + options { + includeTags 'fast' + } + } + + testing { + suites { + test { + useJUnit() // NOT ALLOWED, task is already configured with a framework, should fail-fast here + } + } + }""".stripMargin() when: fails ":test" @@ -217,29 +217,29 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { given: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |testing { - | suites { - | $suiteDeclaration { - | targets { - | all { - | testTask.configure { - | minHeapSize = "128m" - | } - | } - | } - | useJUnitJupiter() - | targets { - | all { - | testTask.configure { - | options { - | ${type} 'fast' - | } - | } - | } - | } - | } - | } - |}""".stripMargin() + testing { + suites { + $suiteDeclaration { + targets { + all { + testTask.configure { + minHeapSize = "128m" + } + } + } + useJUnitJupiter() + targets { + all { + testTask.configure { + options { + ${type} 'fast' + } + } + } + } + } + } + }""".stripMargin() expect: succeeds ":$task" @@ -257,22 +257,22 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { given: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |testing { - | suites { - | $suiteDeclaration { - | useJUnitJupiter() - | targets { - | all { - | testTask.configure { - | options { - | ${type} 'fast' - | } - | } - | } - | } - | } - | } - |}""".stripMargin() + testing { + suites { + $suiteDeclaration { + useJUnitJupiter() + targets { + all { + testTask.configure { + options { + ${type} 'fast' + } + } + } + } + } + } + }""".stripMargin() when: succeeds ":$task" @@ -283,22 +283,22 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { when: resources.maybeCopy("TestOptionsIntegrationSpec") buildFile << """ - |testing { - | suites { - | $suiteDeclaration { - | useJUnitJupiter() - | targets { - | all { - | testTask.configure { - | options { - | ${type} 'slow' - | } - | } - | } - | } - | } - | } - |}""".stripMargin() + testing { + suites { + $suiteDeclaration { + useJUnitJupiter() + targets { + all { + testTask.configure { + options { + ${type} 'slow' + } + } + } + } + } + } + }""".stripMargin() and: succeeds ":$task" @@ -314,8 +314,7 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' } - // Migrated from TestSuitesIntegrationTest to consolidate options-related tests - def "build fails when test framework is changed to another kind when realizing task and configuring options"() { + def "can NOT set new framework for suite in different testing block after configuring options"() { buildFile << """ plugins { id 'java' @@ -342,7 +341,6 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { testing { suites { integrationTest { - // This is ignored useTestNG() } } From eb633d75f850b094587d2f2448e3629a4e21a018 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 14 Sep 2022 14:49:04 -0400 Subject: [PATCH 12/17] Update copyright dates in new resource files --- .../src/integTest/java/org/gradle/SomeTestClass.java | 2 +- .../src/test/java/org/gradle/SomeTestClass.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java index 5428069719fc..0bf1af76a42c 100644 --- a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java +++ b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/integTest/java/org/gradle/SomeTestClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java index 5428069719fc..0bf1af76a42c 100644 --- a/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java +++ b/subprojects/testing-jvm/src/integTest/resources/org/gradle/testing/TestOptionsIntegrationSpec/src/test/java/org/gradle/SomeTestClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 9441e5e31c59194a245035bebcdbc6a2c662c8a2 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 14 Sep 2022 15:00:45 -0400 Subject: [PATCH 13/17] Also test excluding categories --- .../gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy index 42715ee1e6c4..9ab814d3ba44 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/junit/JUnitCategoriesIntegrationSpec.groovy @@ -211,6 +211,6 @@ public class MyTest { skipped ':test' where: - type << ['includeCategories'] + type << ['includeCategories', 'excludeCategories'] } } From 467f607e6a536337d9dfdb5ccdf492f62320ca55 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 14 Sep 2022 15:01:54 -0400 Subject: [PATCH 14/17] Consolidate addditional options related tests, removing a redundant test --- .../testing/TestOptionsIntegrationSpec.groovy | 41 +++++++++- .../TestSuitesIntegrationTest.groovy | 76 ------------------- 2 files changed, 40 insertions(+), 77 deletions(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy index 7b94ff42d4ab..66ef359ebffa 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy @@ -14,8 +14,10 @@ * limitations under the License. */ -package org.gradle.testing; +package org.gradle.testing +import org.gradle.api.tasks.testing.junit.JUnitOptions +import org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions; import org.gradle.integtests.fixtures.AbstractSampleIntegrationTest import org.gradle.integtests.fixtures.TestResources import org.junit.Rule @@ -355,4 +357,41 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { then: result.assertHasErrorOutput("You cannot set the test framework on suite: integrationTest after accessing test options on an associated Test task: integrationTest.") } + + def "can NOT change test framework in test task after options have been set within test suites"() { + buildFile << """ + plugins { + id 'java' + } + + ${mavenCentralRepository()} + + testing { + suites { + integrationTest(JvmTestSuite) { + useJUnit() + targets.all { + testTask.configure { + options { + excludeCategories "com.example.Exclude" + } + } + } + } + } + } + + integrationTest { + useTestNG() + } + + check.dependsOn testing.suites + """ + + when: + fails("check") + + then: + failure.assertHasErrorOutput("You cannot change the test framework to: Test NG after accessing test options. The current framework is: JUnit 4.") + } } diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy index 3b47364ccb1e..04f14f1cb477 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy @@ -479,82 +479,6 @@ class TestSuitesIntegrationTest extends AbstractIntegrationSpec { succeeds("checkConfiguration") } - def "test framework can not be changed once options have been used with test suites"() { - buildFile << """ - plugins { - id 'java' - } - - ${mavenCentralRepository()} - - testing { - suites { - integrationTest(JvmTestSuite) { - useJUnit() - targets.all { - testTask.configure { - options { - excludeCategories "com.example.Exclude" - } - } - } - } - } - } - - integrationTest { - useTestNG() - } - - check.dependsOn testing.suites - """ - - when: - fails("check") - - then: - failure.assertHasErrorOutput("You cannot change the test framework to: Test NG after accessing test options. The current framework is: JUnit 4.") - } - - def "can change not the test framework multiple times before execution when not using test suites"() { - given: - buildFile << """ - plugins { - id 'java' - } - ${mavenCentralRepository()} - dependencies { testImplementation "junit:junit:4.13" } - - test { - useJUnit() - options { - assert it instanceof ${JUnitOptions.canonicalName} - } - useJUnitPlatform() - options { - assert it instanceof ${JUnitPlatformOptions.canonicalName} - } - useJUnit() - } - """ - - and: - file("src/test/java/SomeTest.java") << """ - import org.junit.*; - - public class SomeTest { - @Test public void foo() { - } - } - """ - - when: - fails("test") - - then: - failure.assertHasErrorOutput("You cannot change the test framework to: JUnit Platform after accessing test options. The current framework is: JUnit 4.") - } - @Issue("https://github.com/gradle/gradle/issues/18622") def "custom Test tasks eagerly realized prior to Java and Test Suite plugin application do not fail to be configured when combined with test suites"() { buildFile << """ From aa64e52c96754a60358eba0265e8d6391b73e861 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 14 Sep 2022 15:14:01 -0400 Subject: [PATCH 15/17] Remove unused imports --- .../gradle/testing/testsuites/TestSuitesIntegrationTest.groovy | 2 -- 1 file changed, 2 deletions(-) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy index 04f14f1cb477..b67ed0660c1b 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/testsuites/TestSuitesIntegrationTest.groovy @@ -20,8 +20,6 @@ import org.gradle.api.internal.tasks.testing.junit.JUnitTestFramework import org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestFramework import org.gradle.api.internal.tasks.testing.testng.TestNGTestFramework import org.gradle.api.plugins.jvm.internal.DefaultJvmTestSuite -import org.gradle.api.tasks.testing.junit.JUnitOptions -import org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions import org.gradle.integtests.fixtures.AbstractIntegrationSpec import org.gradle.integtests.fixtures.JUnitXmlTestExecutionResult import spock.lang.Issue From 8360456e1c1fcd7598cd2b96dc6815d8966b8986 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 14 Sep 2022 15:22:51 -0400 Subject: [PATCH 16/17] Print name of test framework the user is attempting to set in test suite in error message if attempt fails due to test options already being accessed --- .../jvm/internal/DefaultJvmTestSuite.java | 27 +++++++++++++------ .../testing/TestOptionsIntegrationSpec.groovy | 12 ++++----- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java b/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java index 2327e490571e..4d2115cf9c26 100644 --- a/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java +++ b/subprojects/plugins/src/main/java/org/gradle/api/plugins/jvm/internal/DefaultJvmTestSuite.java @@ -52,20 +52,23 @@ public abstract class DefaultJvmTestSuite implements JvmTestSuite { public enum Frameworks { - JUNIT4("junit:junit", "4.13.2"), - JUNIT_JUPITER("org.junit.jupiter:junit-jupiter", "5.8.2"), - SPOCK("org.spockframework:spock-core", "2.1-groovy-3.0"), - KOTLIN_TEST("org.jetbrains.kotlin:kotlin-test-junit5", "1.7.10"), - TESTNG("org.testng:testng", "7.5"), - NONE(null, null); + JUNIT4("JUnit 4", "junit:junit", "4.13.2"), + JUNIT_JUPITER("JUnit Jupiter", "org.junit.jupiter:junit-jupiter", "5.8.2"), + SPOCK("Spock", "org.spockframework:spock-core", "2.1-groovy-3.0"), + KOTLIN_TEST("Kotlin Test", "org.jetbrains.kotlin:kotlin-test-junit5", "1.7.10"), + TESTNG("Test NG", "org.testng:testng", "7.5"), + NONE(null, null, null); + @Nullable + private final String displayName; @Nullable private final String module; @Nullable private final String defaultVersion; - Frameworks(@Nullable String module, @Nullable String defaultVersion) { + Frameworks(@Nullable String displayName, @Nullable String module, @Nullable String defaultVersion) { Preconditions.checkArgument(module != null && defaultVersion != null || module == null && defaultVersion == null, "Either module and version must both be null, or neither be null."); + this.displayName = displayName; this.module = module; this.defaultVersion = defaultVersion; } @@ -88,6 +91,13 @@ public String getDependency(String version) { return null; } } + + /** + * How we describe this test framework to the user (i.e., in error messages). + */ + public String getDisplayName() { + return displayName; + } } private static class VersionedTestingFramework { @@ -309,8 +319,9 @@ private void setFrameworkTo(Frameworks framework, Provider versionProvid this.targets.withType(JvmTestSuiteTarget.class).configureEach(target -> { target.getTestTask().configure(task -> { if (task.getOptionsAccessed()) { - throw new GradleException(String.format("You cannot set the test framework on suite: %s after accessing test options on an associated Test task: %s.", + throw new GradleException(String.format("You cannot set the test framework on suite: %s to: %s after accessing test options on an associated Test task: %s.", getName(), + framework.getDisplayName(), task.getName())); } }); diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy index 66ef359ebffa..c4ed4649ca8b 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy @@ -16,8 +16,6 @@ package org.gradle.testing -import org.gradle.api.tasks.testing.junit.JUnitOptions -import org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions; import org.gradle.integtests.fixtures.AbstractSampleIntegrationTest import org.gradle.integtests.fixtures.TestResources import org.junit.Rule @@ -113,7 +111,7 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { fails ":$task" then: - result.assertHasErrorOutput("You cannot set the test framework on suite: $suiteName after accessing test options on an associated Test task: $task.") + result.assertHasErrorOutput("You cannot set the test framework on suite: $suiteName to: JUnit Jupiter after accessing test options on an associated Test task: $task.") where: suiteName | suiteDeclaration | task | type @@ -154,7 +152,7 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { fails ":$task" then: - result.assertHasErrorOutput("You cannot set the test framework on suite: $suiteName after accessing test options on an associated Test task: $task.") + result.assertHasErrorOutput("You cannot set the test framework on suite: $suiteName to: JUnit Jupiter after accessing test options on an associated Test task: $task.") where: suiteName | suiteDeclaration | task | type @@ -186,7 +184,7 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { fails ":test" then: - result.assertHasErrorOutput("You cannot set the test framework on suite: test after accessing test options on an associated Test task: test.") + result.assertHasErrorOutput("You cannot set the test framework on suite: test to: JUnit Jupiter after accessing test options on an associated Test task: test.") } def "can NOT set options on test task directly, outside of default test suite, then again inside suite"() { @@ -212,7 +210,7 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { fails ":test" then: - result.assertHasErrorOutput("You cannot set the test framework on suite: test after accessing test options on an associated Test task: test.") + result.assertHasErrorOutput("You cannot set the test framework on suite: test to: JUnit 4 after accessing test options on an associated Test task: test.") } def "can set non-options test property for test task in #suiteName prior to setting framework within suite"() { @@ -355,7 +353,7 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { fails("check") then: - result.assertHasErrorOutput("You cannot set the test framework on suite: integrationTest after accessing test options on an associated Test task: integrationTest.") + result.assertHasErrorOutput("You cannot set the test framework on suite: integrationTest to: Test NG after accessing test options on an associated Test task: integrationTest.") } def "can NOT change test framework in test task after options have been set within test suites"() { From 2ccafe8fd7c1684226d6f966a9f6c29945c64971 Mon Sep 17 00:00:00 2001 From: Thomas Tresansky Date: Wed, 21 Sep 2022 16:55:38 -0400 Subject: [PATCH 17/17] Clarify can set options prior to framework in suite or task directly in either order --- .../testing/TestOptionsIntegrationSpec.groovy | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy index c4ed4649ca8b..d8a94bbb894a 100644 --- a/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy +++ b/subprojects/testing-jvm/src/integTest/groovy/org/gradle/testing/TestOptionsIntegrationSpec.groovy @@ -252,6 +252,83 @@ class TestOptionsIntegrationSpec extends AbstractSampleIntegrationTest { 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' } + def "can set test framework in test task prior to setting #type option within #suiteName suite"() { + given: + resources.maybeCopy("TestOptionsIntegrationSpec") + buildFile << """ + // Ensure non-default suites exist + testing { + suites { + $suiteDeclaration + } + } + + // Configure task directly using name + $task { + useJUnitPlatform() + } + + // Configure task through suite + testing.suites.$suiteName { + useJUnitJupiter() + targets { + all { + testTask.configure { + options { + ${type} 'fast' + } + } + } + } + }""".stripMargin() + + expect: + succeeds ":$task" + + where: + suiteName | suiteDeclaration | task | type + 'test' | 'test' | 'test' | 'includeTags' + 'test' | 'test' | 'test' | 'excludeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' + } + + def "can set test framework in #suiteName suite prior to setting #type option within test task"() { + given: + resources.maybeCopy("TestOptionsIntegrationSpec") + buildFile << """ + // Configure task through suite + testing { + suites { + $suiteDeclaration { + useJUnitJupiter() + dependencies { + implementation 'org.junit.jupiter:junit-jupiter-engine:5.4.2' + } + } + } + } + + // Configure task directly using name + $task { + options { + ${type} 'fast' + } + } + + """.stripMargin() + + expect: + succeeds ":$task" + + where: + suiteName | suiteDeclaration | task | type + 'test' | 'test' | 'test' | 'includeTags' + 'test' | 'test' | 'test' | 'excludeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'includeTags' + 'integTest' | 'integTest(JvmTestSuite)' | 'integTest' | 'excludeTags' + } + // See JUnitCategoriesIntegrationSpec for the inspiration for this test def "re-executes test when #type is changed in #suiteName"() { given: