Skip to content

Commit

Permalink
[Junit Platform] Support cucumber.filter.name
Browse files Browse the repository at this point in the history
A typical way to run a single Cucumber test from the command line is to use a
filter. The Cucumber Engine already supported `cucumber.filter.tags` but did
not yet support `cucumber.filter.name`.

This filter can be used in `junit-platform.properties`, the CLI (e.g.
`mvn test -Dcucumber.filter.name="^Hello (World|Cucumber)$"` and in any way
properties can be used with the JUnit Platform.
  • Loading branch information
mpkorstanje committed Jul 23, 2020
1 parent bd576bd commit ad58550
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 54 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased] (In Git)

### Added

* [Junit Platform] Support cucumber.filter.name ([#2065](https://github.com/cucumber/cucumber-jvm/issues/2065) M.P. Korstanje)

### Changed

### Deprecated

### Removed

### Fixed
* [Core] Generate valid parameter names in snippets ([#2029](https://github.com/cucumber/cucumber-jvm/issues/2029) M.P. Korstanje)

## [6.1.1] (2020-06-12)

Expand Down
45 changes: 34 additions & 11 deletions core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,49 @@ Note that options provided by `@CucumberOptions` take precedence over the
properties file and CLI arguments take precedence over all.

Note that the `cucumber-junit-platform-engine` is provided with properties
by the Junit Platform rather then Cucumber. See
by the Junit Platform rather than Cucumber. See
[junit-platform-engine Configuration Options](../junit-platform-engine#configuration-options)
for more information.

Supported properties are:

```
cucumber.ansi-colors.disabled= # true or false. default: false
cucumber.execution.dry-run= # true or false. default: false
cucumber.execution.limit= # number of scenarios to execute (CLI only).
cucumber.ansi-colors.disabled= # true or false. default: false
cucumber.execution.dry-run= # true or false. default: false
cucumber.execution.limit= # number of scenarios to execute (CLI only).
cucumber.execution.order= # lexical, reverse, random or random:[seed] (CLI only). default: lexical
cucumber.execution.strict= # true or false. default: false.
cucumber.execution.wip= # true or false. default: false.
cucumber.features= # command separated paths to feature files. example: path/to/example.feature, path/to/other.feature
cucumber.filter.name= # regex. example: .*Hello.*
cucumber.filter.tags= # tag expression. example: @smoke and not @slow
cucumber.glue= # comma separated package names. example: com.example.glue
cucumber.plugin= # comma separated plugin strings. example: pretty, json:path/to/report.json
cucumber.object-factory= # object factory class name. example: com.example.MyObjectFactory
cucumber.snippet-type= # underscore or camelcase. default: underscore
# Fails if there any passing scenarios
# CLI only.
cucumber.features= # command separated paths to feature files.
# example: path/to/example.feature, path/to/other.feature
cucumber.filter.name= # a regular expression
# only scenarios with matching names are executed.
# example: ^Hello (World|Cucumber)$
cucumber.filter.tags= # a cucumber tag expression.
# only scenarios with matching tags are executed.
# example: @Cucumber and not (@Gherkin or @Zucchini)
cucumber.glue= # comma separated package names.
# example: com.example.glue
cucumber.plugin= # comma separated plugin strings.
# example: pretty, json:path/to/report.json
cucumber.object-factory= # object factory class name.
# example: com.example.MyObjectFactory
cucumber.snippet-type= # underscore or camelcase.
# default: underscore
```

Each property also has an `UPPER_CASE` and `snake_case` variant. For example
Expand Down
13 changes: 8 additions & 5 deletions core/src/main/java/io/cucumber/core/options/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,20 @@ public final class Constants {
/**
* Property name used to set name filter: {@value}
* <p>
* Filters features based on the provided regex pattern.
* Filters scenarios by name based on the provided regex pattern e.g:
* {@code ^Hello (World|Cucumber)$}. Scenarios that do not match
* the expression are not executed.
* <p>
* By default no features are filtered
* By default all scenarios are executed
*/
public static final String FILTER_NAME_PROPERTY_NAME = "cucumber.filter.name";

/**
* Property name used to set tag filter: {@value}
* <p>
* Filters scenarios based on the provided tag expression e.g:
* {@code @Integration and not @Ignored}. Scenarios that do not match the
* expression are not executed.
* Filters scenarios by tag based on the provided tag expression e.g:
* {@code @Cucumber and not (@Gherkin or @Zucchini)}. Scenarios that do not
* match the expression are not executed.
* <p>
* By default all scenarios are executed
*/
Expand Down
37 changes: 30 additions & 7 deletions core/src/main/resources/io/cucumber/core/options/USAGE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,41 @@ Supported properties are:

```
cucumber.ansi-colors.disabled= # true or false. default: false

cucumber.execution.dry-run= # true or false. default: false

cucumber.execution.limit= # number of scenarios to execute (CLI only).

cucumber.execution.order= # lexical, reverse, random or random:[seed] (CLI only). default: lexical

cucumber.execution.strict= # true or false. default: false.

cucumber.execution.wip= # true or false. default: false.
cucumber.features= # command separated paths to feature files. example: path/to/example.feature, path/to/other.feature
cucumber.filter.name= # regex. example: .*Hello.*
cucumber.filter.tags= # tag expression. example: @smoke and not @slow
cucumber.glue= # comma separated package names. example: com.example.glue
cucumber.plugin= # comma separated plugin strings. example: pretty, json:path/to/report.json
cucumber.object-factory= # object factory class name. example: com.example.MyObjectFactory
cucumber.snippet-type= # underscore or camelcase. default: underscore
# Fails if there any passing scenarios
# CLI only.

cucumber.features= # command separated paths to feature files.
# example: path/to/example.feature, path/to/other.feature

cucumber.filter.name= # a regular expression
# only scenarios with matching names are executed.
# example: ^Hello (World|Cucumber)$

cucumber.filter.tags= # a cucumber tag expression.
# only scenarios with matching tags are executed.
# example: @Cucumber and not (@Gherkin or @Zucchini)

cucumber.glue= # comma separated package names.
# example: com.example.glue

cucumber.plugin= # comma separated plugin strings.
# example: pretty, json:path/to/report.json

cucumber.object-factory= # object factory class name.
# example: com.example.MyObjectFactory

cucumber.snippet-type= # underscore or camelcase.
# default: underscore
```

Each property also has an `UPPER_CASE` and `snake_case` variant. For example
Expand Down
32 changes: 18 additions & 14 deletions junit-platform-engine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,49 +170,53 @@ Note: The `@` is not included.
## Configuration Options ##

Cucumber receives its configuration from the JUnit platform. To see how these
can be supplied see the JUnit documentation [4.5. Configuration Parameters](https://junit.org/junit5/docs/current/user-guide/#running-tests-config-params).
can be supplied; see the JUnit documentation [4.5. Configuration Parameters](https://junit.org/junit5/docs/current/user-guide/#running-tests-config-params).
For documentation see [Constants](src/main/java/io/cucumber/junit/platform/engine/Constants.java).

```
cucumber.ansi-colors.disabled= # true or false. default: false
cucumber.filter.name= # a regular expression
# only scenarios with matching names are executed.
# example: ^Hello (World|Cucumber)$
cucumber.filter.tags= # a cucumber tag expression.
# only matching scenarios are executed.
# example: @integration and not @disabled
# only scenarios with matching tags are executed.
# example: @Cucumber and not (@Gherkin or @Zucchini)
cucumber.glue= # comma separated package names.
# example: com.example.glue
cucumber.plugin= # comma separated plugin strings.
# example: pretty, json:path/to/report.json
cucumber.object-factory= # object factory class name.
# example: com.example.MyObjectFactory
cucumber.snippet-type= # underscore or camelcase.
# default: underscore
cucumber.execution.dry-run= # true or false.
# default: false
cucumber.execution.parallel.enabled= # true or false.
# default: false
cucumber.execution.parallel.config.strategy= # dynamic, fixed or custom.
# default: dynamic
cucumber.execution.parallel.config.fixed.parallelism= # positive integer.
# example: 4
cucumber.execution.parallel.config.dynamic.factor= # positive double.
# default: 1.0
cucumber.execution.parallel.config.custom.class= # class name.
# example: com.example.MyCustomParallelStrategy
cucumber.execution.exclusive-resources.<tag-name>.read-write= # a comma seperated list of strings
# example: resource-a, resource-b
cucumber.execution.exclusive-resources.<tag-name>.read= # a comma seperated list of strings
# example: resource-a, resource-b
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,36 @@ public final class Constants {
* By default, dry-run is disabled
*/
public static final String EXECUTION_DRY_RUN_PROPERTY_NAME = io.cucumber.core.options.Constants.EXECUTION_DRY_RUN_PROPERTY_NAME;

/**
* Tag replacement pattern for the exclusive resource templates: {@value}
*
* @see #EXECUTION_EXCLUSIVE_RESOURCES_READ_WRITE_TEMPLATE
*/
public static final String EXECUTION_EXCLUSIVE_RESOURCES_TAG_TEMPLATE_VARIABLE = "<tag-name>";

/**
* Property name used to set name filter: {@value}
* <p>
* Filters features by name based on the provided regex pattern e.g:
* {@code ^Hello (World|Cucumber)$}. Scenarios that do not match
* the expression are not executed.
* <p>
* By default all scenarios are executed
*/
public static final String FILTER_NAME_PROPERTY_NAME = io.cucumber.core.options.Constants.FILTER_NAME_PROPERTY_NAME;

/**
* Property name used to set tag filter: {@value}
* <p>
* Filters scenarios based on the provided tag expression e.g:
* {@code @Integration and not @Ignored}. Scenarios that did not match the
* expression will be rendered by JUnit as skipped.
* Filters scenarios by tag based on the provided tag expression e.g:
* {@code @Cucumber and not (@Gherkin or @Zucchini)}. Scenarios that do not
* match the expression are not executed.
* <p>
* By default all scenarios are executed
*/
public static final String FILTER_TAGS_PROPERTY_NAME = io.cucumber.core.options.Constants.FILTER_TAGS_PROPERTY_NAME;

/**
* Property name to set the glue path: {@value}
* <p>
Expand All @@ -53,6 +67,7 @@ public final class Constants {
* @see io.cucumber.core.feature.GluePath
*/
public static final String GLUE_PROPERTY_NAME = io.cucumber.core.options.Constants.GLUE_PROPERTY_NAME;

/**
* Property name to enable plugins: {@value}
* <p>
Expand All @@ -76,13 +91,15 @@ public final class Constants {
* registration of 3rd party plugins.
*/
public static final String PLUGIN_PROPERTY_NAME = io.cucumber.core.options.Constants.PLUGIN_PROPERTY_NAME;

/**
* Property name to select custom object factory implementation: {@value}
* <p>
* By default, if a single object factory is available on the class path
* that object factory will be used.
*/
public static final String OBJECT_FACTORY_PROPERTY_NAME = io.cucumber.core.options.Constants.OBJECT_FACTORY_PROPERTY_NAME;

/**
* Property name to control naming convention for generated snippets:
* {@value}
Expand All @@ -92,6 +109,7 @@ public final class Constants {
* By defaults are generated using the under score naming convention.
*/
public static final String SNIPPET_TYPE_PROPERTY_NAME = io.cucumber.core.options.Constants.SNIPPET_TYPE_PROPERTY_NAME;

/**
* Property name used to enable parallel test execution: {@value}
* <p>
Expand All @@ -102,6 +120,7 @@ public final class Constants {
static final String EXECUTION_EXCLUSIVE_RESOURCES_PREFIX = "cucumber.execution.exclusive-resources.";

static final String READ_WRITE_SUFFIX = ".read-write";

/**
* Property template used to describe a mapping of tags to exclusive
* resources: {@value}
Expand Down Expand Up @@ -131,6 +150,7 @@ public final class Constants {
public static final String EXECUTION_EXCLUSIVE_RESOURCES_READ_WRITE_TEMPLATE = EXECUTION_EXCLUSIVE_RESOURCES_PREFIX
+ EXECUTION_EXCLUSIVE_RESOURCES_TAG_TEMPLATE_VARIABLE + READ_WRITE_SUFFIX;
static final String READ_SUFFIX = ".read";

/**
* Property template used to describe a mapping of tags to exclusive
* resources: {@value}
Expand All @@ -143,6 +163,7 @@ public final class Constants {
+ EXECUTION_EXCLUSIVE_RESOURCES_TAG_TEMPLATE_VARIABLE + READ_SUFFIX;

static final String PARALLEL_CONFIG_PREFIX = "cucumber.execution.parallel.config.";

/**
* Property name used to determine the desired configuration strategy:
* {@value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static io.cucumber.core.resource.ClasspathSupport.CLASSPATH_SCHEME_PREFIX;
import static io.cucumber.junit.platform.engine.Constants.ANSI_COLORS_DISABLED_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.EXECUTION_DRY_RUN_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.FILTER_NAME_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.FILTER_TAGS_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.OBJECT_FACTORY_PROPERTY_NAME;
Expand Down Expand Up @@ -59,11 +62,12 @@ public boolean isWip() {
return false;
}

public Expression tagFilter() {
return TagExpressionParser
.parse(configurationParameters
.get(FILTER_TAGS_PROPERTY_NAME)
.orElse(""));
Optional<Expression> tagFilter() {
return configurationParameters.get(FILTER_TAGS_PROPERTY_NAME, TagExpressionParser::parse);
}

Optional<Pattern> nameFilter() {
return configurationParameters.get(FILTER_NAME_PROPERTY_NAME, Pattern::compile);
}

@Override
Expand Down
Loading

0 comments on commit ad58550

Please sign in to comment.