diff --git a/examples/java-calculator-junit5/src/test/java/io/cucumber/examples/junit5/calculator/RunCucumberTest.java b/examples/java-calculator-junit5/src/test/java/io/cucumber/examples/junit5/calculator/RunCucumberTest.java new file mode 100644 index 0000000000..0987d9bbfe --- /dev/null +++ b/examples/java-calculator-junit5/src/test/java/io/cucumber/examples/junit5/calculator/RunCucumberTest.java @@ -0,0 +1,7 @@ +package io.cucumber.examples.junit5.calculator; + +import io.cucumber.junit.platform.engine.Cucumber; + +@Cucumber +public class RunCucumberTest { +} diff --git a/junit-platform-engine/README.md b/junit-platform-engine/README.md index 3cb360a8a3..58e920b8b7 100644 --- a/junit-platform-engine/README.md +++ b/junit-platform-engine/README.md @@ -1,7 +1,7 @@ Cucumber JUnit Platform Engine ============================== -Use JUnit Platform to execute cucumber scenarios. +Use JUnit Platform to execute Cucumber scenarios. Add the `cucumber-junit-platform-engine` dependency to your `pom.xml`: @@ -17,12 +17,34 @@ Add the `cucumber-junit-platform-engine` dependency to your `pom.xml`: This will allow the IntelliJ IDEA, Eclipse, Maven, Gradle, ect, to discover, select and execute Cucumber scenarios. -## Maven Surefire workaround ## +## Surefire and Gradle workarounds -Maven Surefire does not yet support discovery of non-class based test as a -workaround you can use the antrun plugin to start the the JUnit Platform +Maven Surefire and Gradle do not yet support discovery of non-class based tests +(see: [gradle/#4773](https://github.com/gradle/gradle/issues/4773), +[SUREFIRE-1724](https://issues.apache.org/jira/browse/SUREFIRE-1724)). As a +workaround you can either use the `@Cucumber` annotation or the JUnit Platform Console Launcher. +### Use the @Cucumber annotation ### + +Cucumber will scan the package of a class annotated with `@Cucumber` for feature +files. + +```java +package com.example.app; + +import io.cucumber.junit.platform.engine.Cucumber; + +@Cucumber +public class RunCucumberTest { +} +``` + +### Use the JUnit Console Launcher ### + +As a workaround you can use the JUnit Platform Console Launcher by using either +the Maven Antrun plugin or the Gradle JavaExec task. + ```xml .... @@ -69,12 +91,6 @@ Console Launcher. ``` -## Gradle Test workaround ## - -Gradle Test does not yet support discovery of non-class based test ([gradle/#4773](https://github.com/gradle/gradle/issues/4773)). -As a work around you can use a custom task to start the the JUnit Platform -Console Launcher. - ```groovy tasks { @@ -115,6 +131,7 @@ For supported values see [Constants](src/main/java/io/cucumber/junit/platform/en Supported `DiscoverySelector`s are: * `ClasspathRootSelector` * `ClasspathResourceSelector` +* `ClassSelector` * `PackageSelector` * `FileSelector` * `DirectorySelector` diff --git a/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/Cucumber.java b/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/Cucumber.java new file mode 100644 index 0000000000..60041ad247 --- /dev/null +++ b/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/Cucumber.java @@ -0,0 +1,22 @@ +package io.cucumber.junit.platform.engine; + +import org.apiguardian.api.API; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Test discovery annotation. Marks the package of the annotated class for test + * discovery. + *

+ * Some build tools do not support the {@link org.junit.platform.engine.discovery.DiscoverySelectors} + * used by Cucumber. As a work around Cucumber will scan the package of the + * annotated class for feature files and execute them. + */ +@API(status = API.Status.STABLE) +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Cucumber { +} diff --git a/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolver.java b/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolver.java index 44e19e4193..81de0aaed1 100644 --- a/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolver.java +++ b/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolver.java @@ -3,6 +3,7 @@ import org.junit.platform.engine.EngineDiscoveryRequest; import org.junit.platform.engine.Filter; import org.junit.platform.engine.TestDescriptor; +import org.junit.platform.engine.discovery.ClassSelector; import org.junit.platform.engine.discovery.ClasspathResourceSelector; import org.junit.platform.engine.discovery.ClasspathRootSelector; import org.junit.platform.engine.discovery.DirectorySelector; @@ -35,6 +36,7 @@ private void resolve(EngineDiscoveryRequest request, TestDescriptor engineDescri request.getSelectorsByType(ClasspathRootSelector.class).forEach(featureResolver::resolveClasspathRoot); request.getSelectorsByType(ClasspathResourceSelector.class).forEach(featureResolver::resolveClasspathResource); + request.getSelectorsByType(ClassSelector.class).forEach(featureResolver::resolveClass); request.getSelectorsByType(PackageSelector.class).forEach(featureResolver::resolvePackageResource); request.getSelectorsByType(FileSelector.class).forEach(featureResolver::resolveFile); request.getSelectorsByType(DirectorySelector.class).forEach(featureResolver::resolveDirectory); diff --git a/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/FeatureResolver.java b/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/FeatureResolver.java index dfb1fb9152..962cb3e07f 100644 --- a/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/FeatureResolver.java +++ b/junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/FeatureResolver.java @@ -8,6 +8,7 @@ import org.junit.platform.commons.logging.LoggerFactory; import org.junit.platform.engine.TestDescriptor; import org.junit.platform.engine.UniqueId; +import org.junit.platform.engine.discovery.ClassSelector; import org.junit.platform.engine.discovery.ClasspathResourceSelector; import org.junit.platform.engine.discovery.ClasspathRootSelector; import org.junit.platform.engine.discovery.DirectorySelector; @@ -63,6 +64,14 @@ private static void recursivelyMerge(TestDescriptor descriptor, TestDescriptor p ); } + void resolveClass(ClassSelector classSelector) { + Class javaClass = classSelector.getJavaClass(); + Cucumber annotation = javaClass.getAnnotation(Cucumber.class); + if (annotation != null) { + resolvePackageResource(javaClass.getPackage().getName()); + } + } + void resolveDirectory(DirectorySelector selector) { resolvePath(selector.getPath()); } @@ -84,7 +93,10 @@ void resolveFile(FileSelector selector) { } void resolvePackageResource(PackageSelector selector) { - String packageName = selector.getPackageName(); + resolvePackageResource(selector.getPackageName()); + } + + private void resolvePackageResource(String packageName) { featureScanner .scanForResourcesInPackage(packageName, packageFilter) .stream() diff --git a/junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolverTest.java b/junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolverTest.java index 4f15d888f5..264cbef803 100644 --- a/junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolverTest.java +++ b/junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolverTest.java @@ -32,6 +32,7 @@ import static java.util.stream.Collectors.toSet; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClasspathResource; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClasspathRoots; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectDirectory; @@ -210,6 +211,14 @@ void resolveRequestWithMultipleUniqueIdSelector() { ); } + @Test + void resolveRequestWithClassSelector() { + DiscoverySelector resource = selectClass(RunCucumberTest.class); + EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource); + resolver.resolveSelectors(discoveryRequest, testDescriptor); + assertEquals(2, testDescriptor.getChildren().size()); + } + private Optional selectSomePickle(DiscoverySelector resource) { EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource); resolver.resolveSelectors(discoveryRequest, testDescriptor); diff --git a/junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/RunCucumberTest.java b/junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/RunCucumberTest.java new file mode 100644 index 0000000000..2a0f7bcfde --- /dev/null +++ b/junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/RunCucumberTest.java @@ -0,0 +1,5 @@ +package io.cucumber.junit.platform.engine; + +@Cucumber +public class RunCucumberTest { +}