Skip to content

[JUnit Platform] Use EngineDiscoveryRequestResolver #2835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 39 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
47d345c
[JUnit Platform] Use EngineDiscoveryRequestResolver
mpkorstanje Dec 16, 2023
4ea85b3
WIP
mpkorstanje Jan 4, 2024
bd9ac67
WIP
mpkorstanje Jan 4, 2024
b39764c
WIP
mpkorstanje Feb 15, 2024
9440631
Merge branch 'main' into junit-platform-refactor
mpkorstanje Feb 20, 2024
b6ab3cb
Fix formating
mpkorstanje Feb 20, 2024
b78dac7
WIP
mpkorstanje Feb 20, 2024
15c7221
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Jun 13, 2024
c5be199
Fix
mpkorstanje Jun 13, 2024
4596d74
Fix sorting
mpkorstanje Jun 13, 2024
294d880
Clean up
mpkorstanje Jun 13, 2024
17a2881
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Sep 5, 2024
5f2ca2f
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Oct 31, 2024
9002a1f
WIP
mpkorstanje Oct 31, 2024
a68cc19
Extract FeaturesPropertyResolver
mpkorstanje Nov 1, 2024
ac85314
Refactor tests
mpkorstanje Nov 2, 2024
ff5c6d7
Notes
mpkorstanje Nov 2, 2024
300b405
Simplify
mpkorstanje Nov 6, 2024
1a9e1a7
Move tests for tags to CucumberTestEngineTest
mpkorstanje Nov 6, 2024
26b42ca
Move more tests to CucumberTestEngineTest
mpkorstanje Nov 7, 2024
c090dad
Make it look more like Junit
mpkorstanje Nov 8, 2024
4315b80
Instantiate Configuration exactly once
mpkorstanje Nov 8, 2024
daa5eb4
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Nov 21, 2024
a0f84f1
Warn when selectClasspathResource is incorrectly used
mpkorstanje Nov 21, 2024
5c6b17e
Clean up
mpkorstanje Nov 21, 2024
117e1de
Update CHANGELOG
mpkorstanje Nov 24, 2024
514040e
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Jan 16, 2025
abb234c
Remove unused code
mpkorstanje Jan 16, 2025
a54ab73
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Jan 30, 2025
9e42cae
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Feb 9, 2025
cc1c3f5
Use JUnit 5.12.0-RC1
mpkorstanje Feb 9, 2025
4213749
WIP
mpkorstanje Feb 14, 2025
a724633
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Feb 25, 2025
71fb5c7
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Mar 7, 2025
ca78ceb
More WIP
mpkorstanje Mar 7, 2025
f84cf0c
More WIP
mpkorstanje Mar 7, 2025
22b713f
More WIP
mpkorstanje Mar 7, 2025
9c317a0
Merge remote-tracking branch 'origin/main' into junit-platform-refactor
mpkorstanje Apr 11, 2025
a63162a
Polishing
mpkorstanje Apr 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- [JUnit Platform Engine] Added 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)
- [JUnit Platform Engine] Added option order features and scenarios ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)
- [JUnit Platform Engine] Log warnings 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)

### Changed
- [JUnit Platform Engine] Use JUnit's `EngineDiscoveryRequestResolver` to resolve classpath based resources. ([#2835](https://github.com/cucumber/cucumber-jvm/pull/2835) M.P. Korstanje)

## [7.22.0] - 2025-04-05
### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public final class Constants {
* Valid values are {@code lexical}, {@code reverse}, {@code random} or
* {@code random:[seed]}.
* <p>
* By default features are executed in lexical file name order
* By default, features are executed in lexical file name order and
* scenarios in a feature from top to bottom.
*/
public static final String EXECUTION_ORDER_PROPERTY_NAME = "cucumber.execution.order";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@

public final class StandardPickleOrders {

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

private StandardPickleOrders() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.cucumber.plugin.event.Location;
import io.cucumber.plugin.event.Node;

import java.net.URI;
import java.util.Optional;

final class GherkinMessagesExample implements Node.Example {
Expand All @@ -20,6 +21,11 @@ final class GherkinMessagesExample implements Node.Example {
this.rowIndex = rowIndex;
}

@Override
public URI getUri() {
return parent.getUri();
}

@Override
public Location getLocation() {
return GherkinMessagesLocation.from(tableRow.getLocation());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.cucumber.plugin.event.Location;
import io.cucumber.plugin.event.Node;

import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -31,6 +32,11 @@ public Collection<Example> elements() {
return children;
}

@Override
public URI getUri() {
return parent.getUri();
}

@Override
public Location getLocation() {
return location;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.cucumber.plugin.event.Location;
import io.cucumber.plugin.event.Node;

import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -42,6 +43,11 @@ public Collection<Node> elements() {
return children;
}

@Override
public URI getUri() {
return parent.getUri();
}

@Override
public Location getLocation() {
return GherkinMessagesLocation.from(rule.getLocation());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.cucumber.plugin.event.Location;
import io.cucumber.plugin.event.Node;

import java.net.URI;
import java.util.Optional;

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

@Override
public URI getUri() {
return parent.getUri();
}

@Override
public Location getLocation() {
return GherkinMessagesLocation.from(scenario.getLocation());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.cucumber.plugin.event.Location;
import io.cucumber.plugin.event.Node;

import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -34,6 +35,11 @@ public Collection<Examples> elements() {
return children;
}

@Override
public URI getUri() {
return parent.getUri();
}

@Override
public Location getLocation() {
return GherkinMessagesLocation.from(scenario.getLocation());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import io.cucumber.plugin.event.Node;

import java.net.URI;
import java.util.List;

public interface Feature extends Node.Feature {
Expand All @@ -11,8 +10,6 @@ public interface Feature extends Node.Feature {

List<Pickle> getPickles();

URI getUri();

String getSource();

Iterable<?> getParseEvents();
Expand Down
26 changes: 17 additions & 9 deletions cucumber-junit-platform-engine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ like this:

```mermaid
erDiagram
"IDE, Maven, Gradle or Console Launcher" ||--|{ "JUnit Platform" : "requests discovery and execution"
"IDE" ||--|{ "JUnit Platform" : "requests discovery and execution"
"Maven or Gradle" ||--|{ "JUnit Platform" : "requests discovery and execution"
"Console Launcher" ||--|{ "JUnit Platform" : "requests discovery and execution"
"JUnit Platform" ||--|{ "Cucumber Test Engine": "forwards request"
"JUnit Platform" ||--|{ "Jupiter Test Engine": "forwards request"
Expand Down Expand Up @@ -209,11 +210,12 @@ different configurations. Conceptually this looks like this:

```mermaid
erDiagram
"IDE, Maven, Gradle or Console Launcher" ||--|{ "JUnit Platform" : "requests discovery and execution"
"IDE" ||--|{ "JUnit Platform" : "requests discovery and execution"
"Maven or Gradle" ||--|{ "JUnit Platform" : "requests discovery and execution"
"Console Launcher" ||--|{ "JUnit Platform" : "requests discovery and execution"
"JUnit Platform" ||--|{ "Suite Test Engine": "forwards request"
"Suite Test Engine" ||--|{ "@Suite annotated class A" : "discovers and executes"
"Suite Test Engine" ||--|{ "@Suite annotated class B" : "discovers and executes"

"@Suite annotated class A" ||--|{ "JUnit Platform (A)" : "requests discovery and execution"
"@Suite annotated class B" ||--|{ "JUnit Platform (B)" : "requests discovery and execution"
"JUnit Platform (A)" ||--|{ "Cucumber Test Engine (A)": "forwards request"
Expand Down Expand Up @@ -420,14 +422,14 @@ cucumber.junit-platform.naming-strategy= # long or short.
# default: short
# include parent descriptor name in test descriptor.

cucumber.junit-platform.naming-strategy.short.example-name= # number or pickle.
# default: number
# Use example number or pickle name for examples when
cucumber.junit-platform.naming-strategy.short.example-name= # number, number-and-pickle-if-parameterized or pickle.
# default: number-and-pickle-if-parameterized
# Use example number and/or pickle name for examples when
# short naming strategy is used

cucumber.junit-platform.naming-strategy.long.example-name= # number or pickle.
# default: number
# Use example number or pickle name for examples when
cucumber.junit-platform.naming-strategy.long.example-name= # number, number-and-pickle-if-parameterized, or pickle.
# default: number-and-pickle-if-parameterized
# Use example number and/or pickle name for examples when
# long naming strategy is used

cucumber.plugin= # comma separated plugin strings.
Expand Down Expand Up @@ -464,6 +466,12 @@ cucumber.execution.execution-mode.feature= # same_thread or
# concurrent - executes scenarios concurrently on any
# available thread

cucumber.execution.order= # lexical, reverse, random or random:[seed] (CLI only). default: lexical
# default: lexical
# lexical - executes features in lexical uri order, scenarios and examples from top to bottom
# reverse - as lexical, but in reverse
# random - at random. Note: scenarios and examples are only shuffled within their containing element

cucumber.execution.parallel.enabled= # true or false.
# default: false

Expand Down
5 changes: 5 additions & 0 deletions cucumber-junit-platform-engine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-testkit</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.cucumber.junit.platform.engine;

import io.cucumber.plugin.event.Location;
import org.junit.platform.engine.TestSource;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.support.descriptor.AbstractTestDescriptor;

import java.net.URI;

abstract class AbstractCucumberTestDescriptor extends AbstractTestDescriptor {

protected AbstractCucumberTestDescriptor(UniqueId uniqueId, String displayName, TestSource source) {
super(uniqueId, displayName, source);
}

protected abstract URI getUri();

protected abstract Location getLocation();
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package io.cucumber.junit.platform.engine;

import io.cucumber.core.exception.CucumberException;
import io.cucumber.core.feature.FeatureParser;
import io.cucumber.core.gherkin.Feature;
import io.cucumber.core.resource.Resource;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
Expand All @@ -21,4 +25,32 @@ class CachingFeatureParser {
Optional<Feature> parseResource(Resource resource) {
return cache.computeIfAbsent(resource.getUri(), uri -> delegate.parseResource(resource));
}

Optional<Feature> parseResource(org.junit.platform.commons.support.Resource resource) {
return cache.computeIfAbsent(resource.getUri(), uri -> delegate.parseResource(new ResourceAdapter(resource)));
}

private static class ResourceAdapter implements Resource {
private final org.junit.platform.commons.support.Resource resource;

public ResourceAdapter(org.junit.platform.commons.support.Resource resource) {
this.resource = resource;
}

@Override
public URI getUri() {
String name = resource.getName();
try {
return new URI("classpath", name, null);
} catch (URISyntaxException e) {
String message = String.format("Could not create classpath uri for resource '%s'", name);
throw new CucumberException(message, e);
}
}

@Override
public InputStream getInputStream() throws IOException {
return resource.getInputStream();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,11 @@ public final class Constants {
*/
public static final String EXECUTION_MODE_FEATURE_PROPERTY_NAME = "cucumber.execution.execution-mode.feature";

/**
* TODO: Document
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do this.

*/
public static final String EXECUTION_ORDER_PROPERTY_NAME = io.cucumber.core.options.Constants.EXECUTION_ORDER_PROPERTY_NAME;

/**
* Property name used to enable parallel test execution: {@value}
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
* <p>
*
* @deprecated Please use the JUnit Platform Suite to run Cucumber in
* combination with Surefire or Gradle. E.g: <code><pre>{@code
* combination with Surefire or Gradle. E.g:
*
* <pre>{@code
*package com.example;
*
*import org.junit.platform.suite.api.ConfigurationParameter;
Expand All @@ -33,15 +35,15 @@
*
*import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
*
*&#64;Suite
*&#64;SelectPackages("com.example")
*&#64;ConfigurationParameter(
* key = GLUE_PROPERTY_NAME,
* value = "com.example"
*)
*public class RunCucumberTest {
*}
*}</pre></code>
* @Suite
* @SelectPackages("com.example")
* @ConfigurationParameter(
* key = GLUE_PROPERTY_NAME,
* value = "com.example")
* public class RunCucumberTest {
* }
* }</pre>
*
* @see CucumberTestEngine
*/
@API(status = Status.DEPRECATED)
Expand Down
Loading
Loading