diff --git a/README.adoc b/README.adoc index 7b35adf46..b24377724 100644 --- a/README.adoc +++ b/README.adoc @@ -76,6 +76,7 @@ include::{asciidoctor-source}/configuration.adoc[] include::{asciidoctor-source}/configfile.adoc[] include::{asciidoctor-source}/usage.adoc[] include::{asciidoctor-source}/registering-strategies.adoc[] +include::{asciidoctor-source}/surefire-providers.adoc[] include::{asciidoctor-source}/reports.adoc[] include::{asciidoctor-source}/jenkins.adoc[] include::{asciidoctor-source}/refcard.adoc[] diff --git a/core/src/main/java/org/arquillian/smart/testing/configuration/Configuration.java b/core/src/main/java/org/arquillian/smart/testing/configuration/Configuration.java index ca4837287..72847d3a1 100644 --- a/core/src/main/java/org/arquillian/smart/testing/configuration/Configuration.java +++ b/core/src/main/java/org/arquillian/smart/testing/configuration/Configuration.java @@ -31,6 +31,7 @@ public class Configuration implements ConfigurationSection { public static final String SMART_TESTING_MODE = "smart.testing.mode"; public static final String SMART_TESTING_CUSTOM_STRATEGIES = "smart.testing.strategy"; public static final String SMART_TESTING_CUSTOM_STRATEGIES_PATTERN = SMART_TESTING_CUSTOM_STRATEGIES + ".*"; + public static final String SMART_TESTING_CUSTOM_PROVIDERS = "smart.testing.custom.providers"; public static final String SMART_TESTING_APPLY_TO = "smart.testing.apply.to"; public static final String SMART_TESTING_VERSION = "smart.testing.version"; public static final String SMART_TESTING_DISABLE = "smart.testing.disable"; @@ -39,6 +40,7 @@ public class Configuration implements ConfigurationSection { private String[] strategies = new String[0]; private String[] customStrategies = new String[0]; + private String[] customProviders = new String[0]; private RunMode mode; private String applyTo; @@ -138,6 +140,14 @@ public void setStrategiesConfig(Map strategiesConfig) { this.strategiesConfig = strategiesConfig; } + public String[] getCustomProviders() { + return customProviders; + } + + public void setCustomProviders(String[] customProviders) { + this.customProviders = customProviders; + } + public List registerConfigurationItems() { List configItems = new ArrayList<>(); configItems.add(new ConfigurationItem("strategies", SMART_TESTING, new String[0])); @@ -147,6 +157,7 @@ public List registerConfigurationItems() { configItems.add(new ConfigurationItem("debug", SMART_TESTING_DEBUG, false)); configItems.add(new ConfigurationItem("autocorrect", SMART_TESTING_AUTOCORRECT, false)); configItems.add(new ConfigurationItem("customStrategies", SMART_TESTING_CUSTOM_STRATEGIES_PATTERN)); + configItems.add(new ConfigurationItem("customProviders", SMART_TESTING_CUSTOM_PROVIDERS, new String[0])); return configItems; } diff --git a/core/src/main/java/org/arquillian/smart/testing/hub/storage/local/TemporaryInternalFiles.java b/core/src/main/java/org/arquillian/smart/testing/hub/storage/local/TemporaryInternalFiles.java index 00cb46be4..be311992e 100644 --- a/core/src/main/java/org/arquillian/smart/testing/hub/storage/local/TemporaryInternalFiles.java +++ b/core/src/main/java/org/arquillian/smart/testing/hub/storage/local/TemporaryInternalFiles.java @@ -6,25 +6,32 @@ public class TemporaryInternalFiles { private static final String TEMP_REPORT_DIR = "reports"; private static final String SMART_TESTING_SCM_CHANGES = "scm-changes"; - private static final String JUNIT_5_PLATFORM_VERSION = "junit5PlatformVersion"; + private static final String CUSTOM_PROVIDERS_DIRECTORY = "customProviders"; + + private TemporaryInternalFiles() { + } public static String getScmChangesFileName(){ return SMART_TESTING_SCM_CHANGES; } - public static String getJunit5PlatformVersionFileName(String pluginArtifactId){ - return pluginArtifactId + "_" + JUNIT_5_PLATFORM_VERSION; + public static String getCustomProvidersDirName(String pluginArtifactId) { + return pluginArtifactId + "_" + CUSTOM_PROVIDERS_DIRECTORY; } - public String getTestReportDirectoryName(){ - return TEMP_REPORT_DIR; + public static LocalStorageDirectoryAction createCustomProvidersDirAction(File rootDir, + String pluginArtifactId) { + return new LocalStorage(rootDir) + .duringExecution() + .temporary() + .directory(getCustomProvidersDirName(pluginArtifactId)); } - public LocalStorageDirectoryAction createTestReportDirectoryAction(String rootDir){ - return createTestReportDirectoryAction(new File(rootDir)); + public static String getTestReportDirName() { + return TEMP_REPORT_DIR; } - public LocalStorageDirectoryAction createTestReportDirectoryAction(File rootDir){ + public static LocalStorageDirectoryAction createTestReportDirAction(File rootDir) { return new LocalStorage(rootDir) .duringExecution() .temporary() diff --git a/core/src/test/java/org/arquillian/smart/testing/configuration/ConfigurationTest.java b/core/src/test/java/org/arquillian/smart/testing/configuration/ConfigurationTest.java index 4d13413ac..2af5f08ad 100644 --- a/core/src/test/java/org/arquillian/smart/testing/configuration/ConfigurationTest.java +++ b/core/src/test/java/org/arquillian/smart/testing/configuration/ConfigurationTest.java @@ -68,6 +68,8 @@ public void should_load_configuration_with_default_values_if_property_is_not_spe expectedConfiguration.setCustomStrategies( new String[] {"smart.testing.strategy.cool=org.arquillian.smart.testing:strategy-cool:1.0.0", "smart.testing.strategy.experimental=org.arquillian.smart.testing:strategy-experimental:1.0.0"}); + expectedConfiguration.setCustomProviders( + new String[] {"org.foo:my-custom-provider=fully.qualified.name.to.SurefireProviderImpl"}); // when final Configuration actualConfiguration = diff --git a/core/src/test/java/org/arquillian/smart/testing/configuration/ConfigurationUsingPropertyTest.java b/core/src/test/java/org/arquillian/smart/testing/configuration/ConfigurationUsingPropertyTest.java index d41242bea..42a1c9686 100644 --- a/core/src/test/java/org/arquillian/smart/testing/configuration/ConfigurationUsingPropertyTest.java +++ b/core/src/test/java/org/arquillian/smart/testing/configuration/ConfigurationUsingPropertyTest.java @@ -138,6 +138,8 @@ public void should_load_configuration_with_overwriting_system_properties_over_pr new String[] {"smart.testing.strategy.experimental=org.arquillian.smart.testing:strategy-experimental:1.0.0", "smart.testing.strategy.my=org.arquillian.smart.testing:strategy-my:1.0.0", "smart.testing.strategy.cool=org.arquillian.smart.testing:strategy-cool:1.0.1"}); + expectedConfiguration.setCustomProviders( + new String[] {"org.foo:my-custom-provider=fully.qualified.name.to.SurefireProviderImpl"}); // when final Configuration actualConfiguration = @@ -217,6 +219,8 @@ public void should_load_configuration_file_from_a_particular_location() throws I expectedConfiguration.setCustomStrategies( new String[] {"smart.testing.strategy.cool=org.arquillian.smart.testing:strategy-cool:1.0.0", "smart.testing.strategy.experimental=org.arquillian.smart.testing:strategy-experimental:1.0.0"}); + expectedConfiguration.setCustomProviders( + new String[] {"org.foo:my-custom-provider=fully.qualified.name.to.SurefireProviderImpl"}); final File tempConfigFile = getCustomConfigFile(); System.setProperty(SMART_TESTING_CONFIG, tempConfigFile.getAbsolutePath()); diff --git a/core/src/test/resources/configuration/smart-testing.yml b/core/src/test/resources/configuration/smart-testing.yml index 81964895c..a6512e769 100644 --- a/core/src/test/resources/configuration/smart-testing.yml +++ b/core/src/test/resources/configuration/smart-testing.yml @@ -22,3 +22,5 @@ strategiesConfiguration: # inclusions: # - org.package.exclude.* - org.arquillian.package.exclude.* +customProviders: # + - org.foo:my-custom-provider=fully.qualified.name.to.SurefireProviderImpl diff --git a/docs/configfile.adoc b/docs/configfile.adoc index 145f5dce3..34e0f6c91 100644 --- a/docs/configfile.adoc +++ b/docs/configfile.adoc @@ -27,6 +27,7 @@ copyToClipboard:config-file[] <12> This enables transitivity. <13> This defines list of packages to be excluded while applying transitivity. <14> This defines list of packages to be included while applying transitivity. +<15> GroupId and artifactId with fully qualified name of the implementation of SurefireProvider the execution should be delegated to. All parameters in configuration file are optional. If you haven't used any parameter in configuration file, Smart testing will use default value for that parameter. You can look at <<_reference_card, references>> for default value of parameter. @@ -73,6 +74,9 @@ a| A list of custom strategies in the form of key/value. It is important to noti a| strategiesConfiguration a| A list of strategies with it's configuration. + +a| customProviders +a| A pair of groupId and artifactId with fully qualified name of `SurefireProvider` implementation the test execution should be delegated to. For more information see <<_custom_surefire_providers, Custom Surefire Providers>> |=== ==== Report Options diff --git a/docs/surefire-providers.adoc b/docs/surefire-providers.adoc new file mode 100644 index 000000000..96842c444 --- /dev/null +++ b/docs/surefire-providers.adoc @@ -0,0 +1,43 @@ +== Surefire Providers + +Internally, Smart Testing uses its own implementation of `SurefireProvider` where calls Smart Testing API. Then, based on the information retrieved from the classpath, it decides which provider should be used for a delegation of the test execution - eg. JUnit4 or TestNG (in the same way as it is done inside of the Surefire plugin itself). +But some projects may use their own surefire provider implementations or can specify one specific known provider that should scan the classpath and execute the test suite. + +=== Known Surefire Providers + +Known Surefire Providers are those implementations that are part of the Surefire project itself plus one implementation distributed as part of JUnit 5. The complete list of known providers: + +* JUnit 4 +** groupId: `org.apache.maven.surefire` +** artifactId: `surefire-junit4` +** provider implementation: `org.apache.maven.surefire.junit4.JUnit4Provider` + +* JUnit 47 and above +** groupId: `org.apache.maven.surefire` +** artifactId: `surefire-junit47` +** provider implementation: `org.apache.maven.surefire.junitcore.JUnitCoreProvider` + +* JUnit 5 +** groupId: `org.junit.platform` +** artifactId: `junit-platform-surefire-provider` +** provider implementation: `org.junit.platform.surefire.provider.JUnitPlatformProvider` + +* TestNG +** groupId: `org.apache.maven.surefire` +** artifactId: `surefire-testng` +** provider implementation: `org.apache.maven.surefire.testng.TestNGProvider` + +When one of these providers is specified inside of the Surefire's dependencies, then Smart Testing is able to automatically detect it and delegate the execution to it. + +=== Custom Surefire Providers + +If some unknown provider (or some other `SurefireProvider` implementation) is used then it is necessary to set this provider either in the configuration file or using system properties. +The format is a pair of groupId and artifactId with a fully qualified name of the class that implements `SurefireProvider` interface and that should be loaded. For JUnit 5 provider it would look like this (in case of configuration file): +[source, yaml] +---- +customProviders: + - org.junit.platform:junit-platform-surefire-provider=org.junit.platform.surefire.provider.JUnitPlatformProvider +---- +If this is specified then Smart Testing will detect the dependency and delegate the test execution to it. +System property dedicated for this usage is `const:core/src/main/java/org/arquillian/smart/testing/configuration/Configuration.java[name="SMART_TESTING_CUSTOM_PROVIDERS"]` + diff --git a/functional-tests/test-bed/src/main/java/org/arquillian/smart/testing/ftest/testbed/project/ProjectBuilder.java b/functional-tests/test-bed/src/main/java/org/arquillian/smart/testing/ftest/testbed/project/ProjectBuilder.java index 49b786e79..c60353d8d 100644 --- a/functional-tests/test-bed/src/main/java/org/arquillian/smart/testing/ftest/testbed/project/ProjectBuilder.java +++ b/functional-tests/test-bed/src/main/java/org/arquillian/smart/testing/ftest/testbed/project/ProjectBuilder.java @@ -165,7 +165,7 @@ private TestResults accumulatedTestResults() { private boolean isSurefireReportFile(Path path) { return !path.toFile().getAbsolutePath() - .contains(File.separator + new TemporaryInternalFiles().getTestReportDirectoryName()) && path.getFileName() + .contains(File.separator + TemporaryInternalFiles.getTestReportDirName()) && path.getFileName() .toString().startsWith(TEST_REPORT_PREFIX); } } diff --git a/functional-tests/test-bed/src/test/java/org/arquillian/smart/testing/ftest/configurationfile/HistoricalChangesFailedTestsSelectionExecutionWithConfigFileFunctionalTest.java b/functional-tests/test-bed/src/test/java/org/arquillian/smart/testing/ftest/configurationfile/HistoricalChangesFailedTestsSelectionExecutionWithConfigFileFunctionalTest.java index e1d0c4122..7244a4bff 100644 --- a/functional-tests/test-bed/src/test/java/org/arquillian/smart/testing/ftest/configurationfile/HistoricalChangesFailedTestsSelectionExecutionWithConfigFileFunctionalTest.java +++ b/functional-tests/test-bed/src/test/java/org/arquillian/smart/testing/ftest/configurationfile/HistoricalChangesFailedTestsSelectionExecutionWithConfigFileFunctionalTest.java @@ -62,6 +62,6 @@ public void should_only_execute_previously_failing_tests_when_failed_is_enabled( .containsAll(expectedTestResults) .hasSameSizeAs(expectedTestResults); - softly.assertThat(project).doesNotContainDirectory(new TemporaryInternalFiles().getTestReportDirectoryName()); + softly.assertThat(project).doesNotContainDirectory(TemporaryInternalFiles.getTestReportDirName()); } } diff --git a/functional-tests/test-bed/src/test/java/org/arquillian/smart/testing/ftest/failed/LocalChangesFailedTestsSelectionExecutionFunctionalTest.java b/functional-tests/test-bed/src/test/java/org/arquillian/smart/testing/ftest/failed/LocalChangesFailedTestsSelectionExecutionFunctionalTest.java index bb16dd3f7..1e475bbcf 100644 --- a/functional-tests/test-bed/src/test/java/org/arquillian/smart/testing/ftest/failed/LocalChangesFailedTestsSelectionExecutionFunctionalTest.java +++ b/functional-tests/test-bed/src/test/java/org/arquillian/smart/testing/ftest/failed/LocalChangesFailedTestsSelectionExecutionFunctionalTest.java @@ -58,6 +58,6 @@ public void should_only_execute_previously_failing_tests_when_failed_is_enabled( .containsAll(expectedTestResults) .hasSameSizeAs(expectedTestResults); - softly.assertThat(project).doesNotContainDirectory(new TemporaryInternalFiles().getTestReportDirectoryName()); + softly.assertThat(project).doesNotContainDirectory(TemporaryInternalFiles.getTestReportDirName()); } } diff --git a/known-surefire-providers/pom.xml b/known-surefire-providers/pom.xml new file mode 100644 index 000000000..74e95b60d --- /dev/null +++ b/known-surefire-providers/pom.xml @@ -0,0 +1,14 @@ + + + + smart-testing-parent + org.arquillian.smart.testing + 0.0.6-SNAPSHOT + + 4.0.0 + + known-surefire-providers + + diff --git a/known-surefire-providers/src/main/java/org/arquillian/smart/testing/known/surefire/providers/KnownProvider.java b/known-surefire-providers/src/main/java/org/arquillian/smart/testing/known/surefire/providers/KnownProvider.java new file mode 100644 index 000000000..3c0ae0191 --- /dev/null +++ b/known-surefire-providers/src/main/java/org/arquillian/smart/testing/known/surefire/providers/KnownProvider.java @@ -0,0 +1,46 @@ +package org.arquillian.smart.testing.known.surefire.providers; + +public enum KnownProvider { + + JUNIT_4( + "org.apache.maven.surefire", + "surefire-junit4", + "org.apache.maven.surefire.junit4.JUnit4Provider"), + + JUNIT_47( + "org.apache.maven.surefire", + "surefire-junit47", + "org.apache.maven.surefire.junitcore.JUnitCoreProvider"), + + JUNIT_5( + "org.junit.platform", + "junit-platform-surefire-provider", + "org.junit.platform.surefire.provider.JUnitPlatformProvider"), + + TESTNG( + "org.apache.maven.surefire", + "surefire-testng", + "org.apache.maven.surefire.testng.TestNGProvider"); + + private final String groupId; + private final String artifactId; + private final String providerClassName; + + KnownProvider(String groupId, String artifactId, String providerClassName) { + this.groupId = groupId; + this.artifactId = artifactId; + this.providerClassName = providerClassName; + } + + public String getGroupId() { + return groupId; + } + + public String getArtifactId() { + return artifactId; + } + + public String getProviderClassName() { + return providerClassName; + } +} diff --git a/mvn-extension/pom.xml b/mvn-extension/pom.xml index dbda8c5a8..9bfd5fbe2 100644 --- a/mvn-extension/pom.xml +++ b/mvn-extension/pom.xml @@ -21,6 +21,11 @@ core ${project.version} + + org.arquillian.smart.testing + known-surefire-providers + ${project.version} +