Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- [Core] Emit Suggestion message ([#3073](https://github.com/cucumber/cucumber-jvm/pull/3073) M.P. Korstanje)
- [JUnit Platform Engine] Warn when surefire naming strategy is used ([#3067](https://github.com/cucumber/cucumber-jvm/pull/3067) M.P. Korstanje)

### Fixed
- [Core] Emit StepMatchArgumentsList for ambiguous steps ([#3066](https://github.com/cucumber/cucumber-jvm/pull/3066) M.P. Korstanje)
Expand Down
29 changes: 25 additions & 4 deletions cucumber-junit-platform-engine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@ To improve the readability of the reports use the
`cucumber.junit-platform.naming-strategy` configuration parameter. This will
include the feature name, scenario name, example number, etc. in the report.

For `3.5.2` and below use:

```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<version>3.5.2</version>
<configuration>
<properties>
<configurationParameters>
Expand All @@ -77,6 +79,23 @@ include the feature name, scenario name, example number, etc. in the report.
</properties>
</configuration>
</plugin>
```

For `3.5.4` and above use:

```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.4</version>
<configuration>
<properties>
<configurationParameters>
cucumber.junit-platform.naming-strategy=long
</configurationParameters>
</properties>
</configuration>
</plugin>
```

```kotlin
Expand Down Expand Up @@ -456,7 +475,9 @@ cucumber.junit-platform.discovery.as-root-engine # true or false
cucumber.junit-platform.naming-strategy= # long, short or surefire.
# default: short
# long: include parent descriptor names in test descriptor.
# surefire: Workaround to make test names appear nicely with Surefire.
# surefire: Workaround to make test names appear nicely
# with Surefire < 3.5.3. For 3.5.4 and above use the long
# strategy.

cucumber.junit-platform.naming-strategy.short.example-name= # number, number-and-pickle-if-parameterized or pickle.
# default: number-and-pickle-if-parameterized
Expand Down Expand Up @@ -736,15 +757,15 @@ Note: any files written by Cucumber will be overwritten during the rerun.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<version>3.5.4</version>
<configuration>
<rerunFailingTestsCount>2</rerunFailingTestsCount>
<properties>
<!-- Work around. Surefire does not include enough
information to disambiguate between different
examples and scenarios. -->
<configurationParameters>
cucumber.junit-platform.naming-strategy=surefire
cucumber.junit-platform.naming-strategy=long
</configurationParameters>
</properties>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,13 @@ public final class Constants {
* {@code Feature Name - Rule Name - Scenario Name - Examples Name - Example #N }.
* This is useful for tools that only report the test name such as Gradle.
* <p>
* When the {@code surefire} naming strategy is used nodes are named such
* that the Surefire output makes sense. The feature name will be rendered
* as the class name. The long name without the feature will be rendered as
* the test method name. For example:
* When the {@code surefire} naming strategy is used with Surefire <= 3.5.2,
* nodes are named such the output makes sense. The feature name will be
* rendered as the class name. The long name without the feature will be
* rendered as the test method name. For example:
* {@code Feature Name.Rule Name - Scenario Name - Examples Name - Example #N}.
* <p>
* For Surefire >= 3.5.4 use the {@code long} strategy instead.
*/
@API(status = Status.EXPERIMENTAL, since = "7.0.0")
public static final String JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME = "cucumber.junit-platform.naming-strategy";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.cucumber.tagexpressions.TagExpressionParser;
import org.junit.platform.engine.ConfigurationParameters;
import org.junit.platform.engine.support.config.PrefixedConfigurationParameters;
import org.junit.platform.engine.support.discovery.DiscoveryIssueReporter;
import org.junit.platform.engine.support.hierarchical.Node.ExecutionMode;

import java.net.URI;
Expand Down Expand Up @@ -47,7 +48,10 @@
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PUBLISH_TOKEN_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.SNIPPET_TYPE_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.UUID_GENERATOR_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.DefaultNamingStrategyProvider.SUREFIRE;
import static java.util.Objects.requireNonNull;
import static org.junit.platform.engine.DiscoveryIssue.Severity.WARNING;
import static org.junit.platform.engine.DiscoveryIssue.create;

class CucumberConfiguration implements
io.cucumber.core.plugin.Options,
Expand All @@ -56,9 +60,11 @@ class CucumberConfiguration implements
io.cucumber.core.eventbus.Options {

private final ConfigurationParameters configurationParameters;
private final DiscoveryIssueReporter issueReporter;

CucumberConfiguration(ConfigurationParameters configurationParameters) {
CucumberConfiguration(ConfigurationParameters configurationParameters, DiscoveryIssueReporter issueReporter) {
this.configurationParameters = requireNonNull(configurationParameters);
this.issueReporter = requireNonNull(issueReporter);
}

@Override
Expand Down Expand Up @@ -180,10 +186,22 @@ boolean isParallelExecutionEnabled() {
NamingStrategy namingStrategy() {
return configurationParameters
.get(JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, DefaultNamingStrategyProvider::getStrategyProvider)
.map(this::reportIssueIfSurefireStrategyIsUsed)
.orElse(DefaultNamingStrategyProvider.SHORT)
.create(configurationParameters);
}

private DefaultNamingStrategyProvider reportIssueIfSurefireStrategyIsUsed(DefaultNamingStrategyProvider strategy) {
if (strategy == SUREFIRE) {
issueReporter.reportIssue(create(
WARNING,
String.format(
"The '%s=surefire' naming strategy does not work as expected on Surefire 3.5.4 and above. Upgrade Surefire to at least 3.5.4 and use the 'long' strategy instead.",
JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME)));
}
return strategy;
}

Set<FeatureWithLinesSelector> featuresWithLines() {
return configurationParameters.get(FEATURES_PROPERTY_NAME,
s -> Arrays.stream(s.split(","))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ public String getId() {
public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) {
ConfigurationParameters configurationParameters = discoveryRequest.getConfigurationParameters();
TestSource testSource = createEngineTestSource(configurationParameters);
CucumberConfiguration configuration = new CucumberConfiguration(configurationParameters);
CucumberEngineDescriptor engineDescriptor = new CucumberEngineDescriptor(uniqueId, configuration, testSource);

DiscoveryIssueReporter issueReporter = deduplicating(forwarding( //
discoveryRequest.getDiscoveryListener(), //
engineDescriptor.getUniqueId() //
uniqueId //
));
CucumberConfiguration configuration = new CucumberConfiguration(configurationParameters, issueReporter);
CucumberEngineDescriptor engineDescriptor = new CucumberEngineDescriptor(uniqueId, configuration, testSource);

// Early out if Cucumber is the root engine and discovery has been
// explicitly disabled. Workaround for:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void resolveSelectors(
DiscoveryIssueReporter issueReporter
) {
ConfigurationParameters configuration = request.getConfigurationParameters();
CucumberConfiguration options = new CucumberConfiguration(configuration);
CucumberConfiguration options = new CucumberConfiguration(configuration, issueReporter);
Set<FeatureWithLinesSelector> selectors = options.featuresWithLines();

if (selectors.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
import io.cucumber.core.snippets.SnippetType;
import org.junit.jupiter.api.Test;
import org.junit.platform.engine.ConfigurationParameters;
import org.junit.platform.engine.DiscoveryIssue;
import org.junit.platform.engine.support.discovery.DiscoveryIssueReporter;

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

import static java.util.stream.Collectors.toList;
Expand All @@ -22,20 +26,24 @@

class CucumberConfigurationTest {

private final List<DiscoveryIssue> issues = new ArrayList<>();
private final DiscoveryIssueReporter issueReporter = DiscoveryIssueReporter.collecting(issues);

@Test
void getPluginNames() {
ConfigurationParameters config = new MapConfigurationParameters(
Constants.PLUGIN_PROPERTY_NAME,
"html:path/to/report.html");

assertThat(new CucumberConfiguration(config).plugins().stream()
assertThat(new CucumberConfiguration(config, issueReporter).plugins().stream()
.map(Options.Plugin::pluginString)
.collect(toList()),
hasItem("html:path/to/report.html"));

CucumberConfiguration htmlAndJson = new CucumberConfiguration(
new MapConfigurationParameters(Constants.PLUGIN_PROPERTY_NAME,
"html:path/with spaces/to/report.html, message:path/with spaces/to/report.ndjson"));
"html:path/with spaces/to/report.html, message:path/with spaces/to/report.ndjson"),
issueReporter);

assertThat(htmlAndJson.plugins().stream()
.map(Options.Plugin::pluginString)
Expand All @@ -48,7 +56,7 @@ void getPluginNamesWithPublishToken() {
ConfigurationParameters config = new MapConfigurationParameters(
Constants.PLUGIN_PUBLISH_TOKEN_PROPERTY_NAME, "some/token");

assertThat(new CucumberConfiguration(config).plugins().stream()
assertThat(new CucumberConfiguration(config, issueReporter).plugins().stream()
.map(Options.Plugin::pluginString)
.collect(toList()),
hasItem("io.cucumber.core.plugin.PublishFormatter:some/token"));
Expand All @@ -58,7 +66,7 @@ void getPluginNamesWithPublishToken() {
void getPluginNamesWithNothingEnabled() {
ConfigurationParameters config = new EmptyConfigurationParameters();

assertThat(new CucumberConfiguration(config).plugins().stream()
assertThat(new CucumberConfiguration(config, issueReporter).plugins().stream()
.map(Options.Plugin::pluginString)
.collect(toList()),
empty());
Expand All @@ -69,7 +77,7 @@ void getPluginNamesWithPublishQuiteEnabled() {
ConfigurationParameters config = new MapConfigurationParameters(
Constants.PLUGIN_PUBLISH_QUIET_PROPERTY_NAME, "true");

assertThat(new CucumberConfiguration(config).plugins().stream()
assertThat(new CucumberConfiguration(config, issueReporter).plugins().stream()
.map(Options.Plugin::pluginString)
.collect(toList()),
empty());
Expand All @@ -80,7 +88,7 @@ void getPluginNamesWithPublishEnabled() {
ConfigurationParameters config = new MapConfigurationParameters(
Constants.PLUGIN_PUBLISH_ENABLED_PROPERTY_NAME, "true");

assertThat(new CucumberConfiguration(config).plugins().stream()
assertThat(new CucumberConfiguration(config, issueReporter).plugins().stream()
.map(Options.Plugin::pluginString)
.collect(toList()),
hasItem("io.cucumber.core.plugin.PublishFormatter"));
Expand All @@ -92,7 +100,7 @@ void getPluginNamesWithPublishDisabledAndPublishToken() {
Constants.PLUGIN_PUBLISH_ENABLED_PROPERTY_NAME, "false",
Constants.PLUGIN_PUBLISH_TOKEN_PROPERTY_NAME, "some/token"));

assertThat(new CucumberConfiguration(config).plugins().stream()
assertThat(new CucumberConfiguration(config, issueReporter).plugins().stream()
.map(Options.Plugin::pluginString)
.collect(toList()),
empty());
Expand All @@ -103,12 +111,12 @@ void isMonochrome() {
MapConfigurationParameters ansiColors = new MapConfigurationParameters(
Constants.ANSI_COLORS_DISABLED_PROPERTY_NAME,
"true");
assertTrue(new CucumberConfiguration(ansiColors).isMonochrome());
assertTrue(new CucumberConfiguration(ansiColors, issueReporter).isMonochrome());

MapConfigurationParameters noAnsiColors = new MapConfigurationParameters(
Constants.ANSI_COLORS_DISABLED_PROPERTY_NAME,
"false");
assertFalse(new CucumberConfiguration(noAnsiColors).isMonochrome());
assertFalse(new CucumberConfiguration(noAnsiColors, issueReporter).isMonochrome());
}

@Test
Expand All @@ -117,7 +125,7 @@ void getGlue() {
Constants.GLUE_PROPERTY_NAME,
"com.example.app, com.example.glue");

assertThat(new CucumberConfiguration(config).getGlue(),
assertThat(new CucumberConfiguration(config, issueReporter).getGlue(),
contains(
URI.create("classpath:/com/example/app"),
URI.create("classpath:/com/example/glue")));
Expand All @@ -128,12 +136,12 @@ void isDryRun() {
ConfigurationParameters dryRun = new MapConfigurationParameters(
Constants.EXECUTION_DRY_RUN_PROPERTY_NAME,
"true");
assertTrue(new CucumberConfiguration(dryRun).isDryRun());
assertTrue(new CucumberConfiguration(dryRun, issueReporter).isDryRun());

ConfigurationParameters noDryRun = new MapConfigurationParameters(
Constants.EXECUTION_DRY_RUN_PROPERTY_NAME,
"false");
assertFalse(new CucumberConfiguration(noDryRun).isDryRun());
assertFalse(new CucumberConfiguration(noDryRun, issueReporter).isDryRun());
}

@Test
Expand All @@ -142,28 +150,28 @@ void getSnippetType() {
Constants.SNIPPET_TYPE_PROPERTY_NAME,
"underscore");

assertThat(new CucumberConfiguration(underscore).getSnippetType(), is(SnippetType.UNDERSCORE));
assertThat(new CucumberConfiguration(underscore, issueReporter).getSnippetType(), is(SnippetType.UNDERSCORE));

ConfigurationParameters camelcase = new MapConfigurationParameters(
Constants.SNIPPET_TYPE_PROPERTY_NAME,
"camelcase");
assertThat(new CucumberConfiguration(camelcase).getSnippetType(), is(SnippetType.CAMELCASE));
assertThat(new CucumberConfiguration(camelcase, issueReporter).getSnippetType(), is(SnippetType.CAMELCASE));
}

@Test
void isParallelExecutionEnabled() {
ConfigurationParameters enabled = new MapConfigurationParameters(
Constants.PARALLEL_EXECUTION_ENABLED_PROPERTY_NAME,
"true");
assertTrue(new CucumberConfiguration(enabled).isParallelExecutionEnabled());
assertTrue(new CucumberConfiguration(enabled, issueReporter).isParallelExecutionEnabled());

ConfigurationParameters disabled = new MapConfigurationParameters(
Constants.PARALLEL_EXECUTION_ENABLED_PROPERTY_NAME,
"false");
assertFalse(new CucumberConfiguration(disabled).isParallelExecutionEnabled());
assertFalse(new CucumberConfiguration(disabled, issueReporter).isParallelExecutionEnabled());
ConfigurationParameters absent = new MapConfigurationParameters(
"some key", "some value");
assertFalse(new CucumberConfiguration(absent).isParallelExecutionEnabled());
assertFalse(new CucumberConfiguration(absent, issueReporter).isParallelExecutionEnabled());
}

@Test
Expand All @@ -172,7 +180,7 @@ void objectFactory() {
Constants.OBJECT_FACTORY_PROPERTY_NAME,
DefaultObjectFactory.class.getName());

assertThat(new CucumberConfiguration(configurationParameters).getObjectFactoryClass(),
assertThat(new CucumberConfiguration(configurationParameters, issueReporter).getObjectFactoryClass(),
is(DefaultObjectFactory.class));
}

Expand All @@ -182,7 +190,7 @@ void uuidGenerator() {
Constants.UUID_GENERATOR_PROPERTY_NAME,
IncrementingUuidGenerator.class.getName());

assertThat(new CucumberConfiguration(configurationParameters).getUuidGeneratorClass(),
assertThat(new CucumberConfiguration(configurationParameters, issueReporter).getUuidGeneratorClass(),
is(IncrementingUuidGenerator.class));
}
}
2 changes: 1 addition & 1 deletion examples/calculator-java-junit5/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
<!-- Work around. Surefire does not include enough information to disambiguate between different
examples. -->
<configurationParameters>
cucumber.junit-platform.naming-strategy=surefire
cucumber.junit-platform.naming-strategy=long
</configurationParameters>
</properties>
</configuration>
Expand Down
2 changes: 1 addition & 1 deletion examples/calculator-kotlin-junit5/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
<!-- Work around. Surefire does not include enough information to disambiguate between different
examples. -->
<configurationParameters>
cucumber.junit-platform.naming-strategy=surefire
cucumber.junit-platform.naming-strategy=long
</configurationParameters>
</properties>
</configuration>
Expand Down
2 changes: 1 addition & 1 deletion examples/spring-java-junit5/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
<!-- Work around. Surefire does not include enough information to disambiguate between different
examples. -->
<configurationParameters>
cucumber.junit-platform.naming-strategy=surefire
cucumber.junit-platform.naming-strategy=long
</configurationParameters>
</properties>
</configuration>
Expand Down
Loading