Skip to content

Commit 7e93851

Browse files
authored
[JUnit Platform] Use EngineDiscoveryRequestResolver (#2835)
Cucumber now uses JUnits `EngineDiscoveryRequestResolver`. JUnit provides a `EngineDiscoveryRequestResolver` that handles the resolution of most resources. This removes some complexity from Cucumber. This comes with several implications. #### Classpath resources must be singular feature files. There is now a distinction between the classpath resource and package discovery selectors. The former should be used for individual feature files on the classpath, the latter for directories. So instead of using a class path resource selector for a directory: ```java @suite @IncludeEngines("cucumber") @SelectClasspathResource("com/example") public class RunCucumberTest { } ``` The package selector should be used instead: ```java @suite @IncludeEngines("cucumber") @SelectPackages("com.example") public class RunCucumberTest { } ``` This is still okay: ```java @suite @IncludeEngines("cucumber") @SelectClasspathResource("com/example/my.feature") public class RunCucumberTest { } ``` Using the classpath resource selector on a folder does still work, but the functionality has been deprecated will result in a warning. #### Support `cucumber.execution.order` Features and scenarios are now discovered in arbitrary order and ordered after discovery. This order can be controlled with the `cucumber.execution.order` property. By default features are executed in `lexical` uri order, with scenarios and examples from top to bottom. Other valid options are `reverse` and `random`. There is room to add custom orderer here but this hasn't been implemented yet. #### Use JUnits discovery issue reporting mechanism Any problems with the build are now reported through JUnits discovery issue reporting mechanism. This provides a more robust report than logging warnings.
1 parent 1b014ea commit 7e93851

File tree

62 files changed

+2520
-1756
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2520
-1756
lines changed

.github/workflows/test-java.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ jobs:
3333
run: ./mvnw install -Pinclude-extra-modules -DskipTests=true -DskipITs=true -D"archetype.test.skip=true" -D"maven.javadoc.skip=true" --batch-mode -D"style.color=always" --show-version
3434
- name: Test
3535
run: ./mvnw verify -Pinclude-extra-modules -D"style.color=always"
36-
env:
37-
CUCUMBER_PUBLISH_TOKEN: ${{ secrets.CUCUMBER_PUBLISH_TOKEN }}
3836

3937
javadoc:
4038
name: 'Javadoc'

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1010
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1111

1212
## [Unreleased]
13+
### Added
14+
- [JUnit Platform Engine] Option to include a parameterized scenario name only if the scenario is parameterized ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)
15+
- [JUnit Platform Engine] Option to order features and scenarios ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)
16+
- [JUnit Platform Engine] Log discovery issues when a classpath resource selector is (e.g. `@SelectClasspathResource`) is used to select a directory. ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)
17+
1318
### Changed
19+
- [JUnit Platform Engine] Use JUnit's `EngineDiscoveryRequestResolver` to resolve classpath based resources. ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)
1420
- [JUnit Platform Engine] Use JUnit Platform 1.13.1 (JUnit Jupiter 5.13.1)
1521

22+
### Fixed
23+
- [JUnit Platform Engine] Log discovery issues for feature files with parse errors. ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)
24+
25+
1626
## [7.23.0] - 2025-05-29
1727
### Added
1828
- [JUnit Platform Engine, TestNG] Remove framework elements from `UndefinedStepException` stacktrace ([#3002](https://github.com/cucumber/cucumber-jvm/pull/3002) M.P. Korstanje)

cucumber-core/src/main/java/io/cucumber/core/feature/FeatureIdentifier.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,15 @@ public static URI parse(URI featureIdentifier) {
3232
}
3333

3434
public static boolean isFeature(URI featureIdentifier) {
35-
return featureIdentifier.getSchemeSpecificPart().endsWith(FEATURE_FILE_SUFFIX);
35+
return isFeature(featureIdentifier.getSchemeSpecificPart());
3636
}
3737

3838
public static boolean isFeature(Path path) {
39-
return path.getFileName().toString().endsWith(FEATURE_FILE_SUFFIX);
39+
return isFeature(path.getFileName().toString());
40+
}
41+
42+
public static boolean isFeature(String fileName) {
43+
return fileName.endsWith(FEATURE_FILE_SUFFIX);
4044
}
4145

4246
}

cucumber-core/src/main/java/io/cucumber/core/options/Constants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ public final class Constants {
4242
* Valid values are {@code lexical}, {@code reverse}, {@code random} or
4343
* {@code random:[seed]}.
4444
* <p>
45-
* By default features are executed in lexical file name order
45+
* By default, features are executed in lexical file name order and
46+
* scenarios in a feature from top to bottom.
4647
*/
4748
public static final String EXECUTION_ORDER_PROPERTY_NAME = "cucumber.execution.order";
4849

cucumber-core/src/main/java/io/cucumber/core/order/StandardPickleOrders.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88

99
public final class StandardPickleOrders {
1010

11-
private static final Comparator<Pickle> pickleUriComparator = Comparator.comparing(Pickle::getUri)
12-
.thenComparing(pickle -> pickle.getLocation().getLine());
11+
private static final Comparator<Pickle> pickleUriComparator = Comparator
12+
.comparing(Pickle::getUri)
13+
.thenComparing(Pickle::getLocation);
1314

1415
private StandardPickleOrders() {
1516

cucumber-core/src/main/java/io/cucumber/core/resource/PathScanner.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.cucumber.core.logging.Logger;
44
import io.cucumber.core.logging.LoggerFactory;
5+
import org.apiguardian.api.API;
56

67
import java.io.IOException;
78
import java.net.URI;
@@ -20,8 +21,10 @@
2021
import static java.nio.file.FileVisitResult.CONTINUE;
2122
import static java.nio.file.Files.exists;
2223
import static java.nio.file.Files.walkFileTree;
24+
import static org.apiguardian.api.API.Status.INTERNAL;
2325

24-
class PathScanner {
26+
@API(status = INTERNAL)
27+
public class PathScanner {
2528

2629
private static final Logger log = LoggerFactory.getLogger(PathScanner.class);
2730

@@ -48,10 +51,14 @@ void findResourcesForPath(Path path, Predicate<Path> filter, Function<Path, Cons
4851
if (!exists(path)) {
4952
throw new IllegalArgumentException("path must exist: " + path);
5053
}
54+
findResourcesForPath(path, filter, consumer.apply(path));
55+
}
5156

57+
public void findResourcesForPath(Path path, Predicate<Path> filter, Consumer<Path> consumer) {
5258
try {
53-
walkFileTree(path, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
54-
new ResourceFileVisitor(filter, consumer.apply(path)));
59+
EnumSet<FileVisitOption> options = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
60+
ResourceFileVisitor visitor = new ResourceFileVisitor(filter, consumer);
61+
walkFileTree(path, options, Integer.MAX_VALUE, visitor);
5562
} catch (IOException e) {
5663
throw new RuntimeException(e);
5764
}

cucumber-gherkin-messages/src/main/java/io/cucumber/core/gherkin/messages/GherkinMessagesExample.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.cucumber.plugin.event.Location;
55
import io.cucumber.plugin.event.Node;
66

7+
import java.net.URI;
78
import java.util.Optional;
89

910
final class GherkinMessagesExample implements Node.Example {
@@ -20,6 +21,11 @@ final class GherkinMessagesExample implements Node.Example {
2021
this.rowIndex = rowIndex;
2122
}
2223

24+
@Override
25+
public URI getUri() {
26+
return parent.getUri();
27+
}
28+
2329
@Override
2430
public Location getLocation() {
2531
return GherkinMessagesLocation.from(tableRow.getLocation());

cucumber-gherkin-messages/src/main/java/io/cucumber/core/gherkin/messages/GherkinMessagesExamples.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.cucumber.plugin.event.Location;
44
import io.cucumber.plugin.event.Node;
55

6+
import java.net.URI;
67
import java.util.Collection;
78
import java.util.List;
89
import java.util.Optional;
@@ -31,6 +32,11 @@ public Collection<Example> elements() {
3132
return children;
3233
}
3334

35+
@Override
36+
public URI getUri() {
37+
return parent.getUri();
38+
}
39+
3440
@Override
3541
public Location getLocation() {
3642
return location;

cucumber-gherkin-messages/src/main/java/io/cucumber/core/gherkin/messages/GherkinMessagesRule.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.cucumber.plugin.event.Location;
55
import io.cucumber.plugin.event.Node;
66

7+
import java.net.URI;
78
import java.util.Collection;
89
import java.util.List;
910
import java.util.Optional;
@@ -42,6 +43,11 @@ public Collection<Node> elements() {
4243
return children;
4344
}
4445

46+
@Override
47+
public URI getUri() {
48+
return parent.getUri();
49+
}
50+
4551
@Override
4652
public Location getLocation() {
4753
return GherkinMessagesLocation.from(rule.getLocation());

cucumber-gherkin-messages/src/main/java/io/cucumber/core/gherkin/messages/GherkinMessagesScenario.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.cucumber.plugin.event.Location;
44
import io.cucumber.plugin.event.Node;
55

6+
import java.net.URI;
67
import java.util.Optional;
78

89
final class GherkinMessagesScenario implements Node.Scenario {
@@ -20,6 +21,11 @@ public Optional<Node> getParent() {
2021
return Optional.of(parent);
2122
}
2223

24+
@Override
25+
public URI getUri() {
26+
return parent.getUri();
27+
}
28+
2329
@Override
2430
public Location getLocation() {
2531
return GherkinMessagesLocation.from(scenario.getLocation());

0 commit comments

Comments
 (0)