Skip to content

Commit b044364

Browse files
committed
[JUnit] Add JUnit Platform @cucumber annotation
Maven Surefire and Gradle do not yet support discovery of non-class based tests[1][2]. As a workaround you can either use the `@Cucumber` annotation or the JUnit Platform Console Launcher. 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 { } ``` 1. gradle/gradle#4773 2. https://issues.apache.org/jira/browse/SUREFIRE-1724
1 parent 3dae98a commit b044364

File tree

7 files changed

+85
-11
lines changed

7 files changed

+85
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.cucumber.examples.junit5.calculator;
2+
3+
import io.cucumber.junit.platform.engine.Cucumber;
4+
5+
@Cucumber
6+
public class RunCucumberTest {
7+
}

junit-platform-engine/README.md

+27-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Cucumber JUnit Platform Engine
22
==============================
33

4-
Use JUnit Platform to execute cucumber scenarios.
4+
Use JUnit Platform to execute Cucumber scenarios.
55

66
Add the `cucumber-junit-platform-engine` dependency to your `pom.xml`:
77

@@ -17,12 +17,34 @@ Add the `cucumber-junit-platform-engine` dependency to your `pom.xml`:
1717
This will allow the IntelliJ IDEA, Eclipse, Maven, Gradle, ect, to discover,
1818
select and execute Cucumber scenarios.
1919

20-
## Maven Surefire workaround ##
20+
## Surefire and Gradle workarounds
2121

22-
Maven Surefire does not yet support discovery of non-class based test as a
23-
workaround you can use the antrun plugin to start the the JUnit Platform
22+
Maven Surefire and Gradle do not yet support discovery of non-class based tests
23+
(see: [gradle/#4773](https://github.com/gradle/gradle/issues/4773),
24+
[SUREFIRE-1724](https://issues.apache.org/jira/browse/SUREFIRE-1724)). As a
25+
workaround you can either use the `@Cucumber` annotation or the JUnit Platform
2426
Console Launcher.
2527

28+
### Use the @Cucumber annotation ###
29+
30+
Cucumber will scan the package of a class annotated with `@Cucumber` for feature
31+
files.
32+
33+
```java
34+
package com.example.app;
35+
36+
import io.cucumber.junit.platform.engine.Cucumber;
37+
38+
@Cucumber
39+
public class RunCucumberTest {
40+
}
41+
```
42+
43+
### Use the JUnit Console Launcher ###
44+
45+
As a workaround you can use the JUnit Platform Console Launcher by using either
46+
the Maven Antrun plugin or the Gradle JavaExec task.
47+
2648
```xml
2749
<dependencies>
2850
....
@@ -69,12 +91,6 @@ Console Launcher.
6991
</plugins>
7092
</build>
7193
```
72-
## Gradle Test workaround ##
73-
74-
Gradle Test does not yet support discovery of non-class based test ([gradle/#4773](https://github.com/gradle/gradle/issues/4773)).
75-
As a work around you can use a custom task to start the the JUnit Platform
76-
Console Launcher.
77-
7894
```groovy
7995
8096
tasks {
@@ -115,6 +131,7 @@ For supported values see [Constants](src/main/java/io/cucumber/junit/platform/en
115131
Supported `DiscoverySelector`s are:
116132
* `ClasspathRootSelector`
117133
* `ClasspathResourceSelector`
134+
* `ClassSelector`
118135
* `PackageSelector`
119136
* `FileSelector`
120137
* `DirectorySelector`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.cucumber.junit.platform.engine;
2+
3+
import org.apiguardian.api.API;
4+
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
/**
11+
* Test discovery annotation. Marks the package of the annotated class for test
12+
* discovery.
13+
* <p>
14+
* Some build tools do not support the {@link org.junit.platform.engine.discovery.DiscoverySelectors}
15+
* used by Cucumber. As a work around Cucumber will scan the package of the
16+
* annotated class for feature files and execute them.
17+
*/
18+
@API(status = API.Status.STABLE)
19+
@Retention(RetentionPolicy.RUNTIME)
20+
@Target(ElementType.TYPE)
21+
public @interface Cucumber {
22+
}

junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolver.java

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.junit.platform.engine.EngineDiscoveryRequest;
44
import org.junit.platform.engine.Filter;
55
import org.junit.platform.engine.TestDescriptor;
6+
import org.junit.platform.engine.discovery.ClassSelector;
67
import org.junit.platform.engine.discovery.ClasspathResourceSelector;
78
import org.junit.platform.engine.discovery.ClasspathRootSelector;
89
import org.junit.platform.engine.discovery.DirectorySelector;
@@ -35,6 +36,7 @@ private void resolve(EngineDiscoveryRequest request, TestDescriptor engineDescri
3536

3637
request.getSelectorsByType(ClasspathRootSelector.class).forEach(featureResolver::resolveClasspathRoot);
3738
request.getSelectorsByType(ClasspathResourceSelector.class).forEach(featureResolver::resolveClasspathResource);
39+
request.getSelectorsByType(ClassSelector.class).forEach(featureResolver::resolveClass);
3840
request.getSelectorsByType(PackageSelector.class).forEach(featureResolver::resolvePackageResource);
3941
request.getSelectorsByType(FileSelector.class).forEach(featureResolver::resolveFile);
4042
request.getSelectorsByType(DirectorySelector.class).forEach(featureResolver::resolveDirectory);

junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/FeatureResolver.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.junit.platform.commons.logging.LoggerFactory;
99
import org.junit.platform.engine.TestDescriptor;
1010
import org.junit.platform.engine.UniqueId;
11+
import org.junit.platform.engine.discovery.ClassSelector;
1112
import org.junit.platform.engine.discovery.ClasspathResourceSelector;
1213
import org.junit.platform.engine.discovery.ClasspathRootSelector;
1314
import org.junit.platform.engine.discovery.DirectorySelector;
@@ -63,6 +64,14 @@ private static void recursivelyMerge(TestDescriptor descriptor, TestDescriptor p
6364
);
6465
}
6566

67+
void resolveClass(ClassSelector classSelector) {
68+
Class<?> javaClass = classSelector.getJavaClass();
69+
Cucumber annotation = javaClass.getAnnotation(Cucumber.class);
70+
if (annotation != null) {
71+
resolvePackageResource(javaClass.getPackage().getName());
72+
}
73+
}
74+
6675
void resolveDirectory(DirectorySelector selector) {
6776
resolvePath(selector.getPath());
6877
}
@@ -84,7 +93,10 @@ void resolveFile(FileSelector selector) {
8493
}
8594

8695
void resolvePackageResource(PackageSelector selector) {
87-
String packageName = selector.getPackageName();
96+
resolvePackageResource(selector.getPackageName());
97+
}
98+
99+
private void resolvePackageResource(String packageName) {
88100
featureScanner
89101
.scanForResourcesInPackage(packageName, packageFilter)
90102
.stream()

junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/DiscoverySelectorResolverTest.java

+9
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import static java.util.stream.Collectors.toSet;
3333
import static org.hamcrest.MatcherAssert.assertThat;
3434
import static org.junit.jupiter.api.Assertions.assertEquals;
35+
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
3536
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClasspathResource;
3637
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClasspathRoots;
3738
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectDirectory;
@@ -210,6 +211,14 @@ void resolveRequestWithMultipleUniqueIdSelector() {
210211
);
211212
}
212213

214+
@Test
215+
void resolveRequestWithClassSelector() {
216+
DiscoverySelector resource = selectClass(RunCucumberTest.class);
217+
EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource);
218+
resolver.resolveSelectors(discoveryRequest, testDescriptor);
219+
assertEquals(2, testDescriptor.getChildren().size());
220+
}
221+
213222
private Optional<UniqueId> selectSomePickle(DiscoverySelector resource) {
214223
EngineDiscoveryRequest discoveryRequest = new SelectorRequest(resource);
215224
resolver.resolveSelectors(discoveryRequest, testDescriptor);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.cucumber.junit.platform.engine;
2+
3+
@Cucumber
4+
public class RunCucumberTest {
5+
}

0 commit comments

Comments
 (0)