Skip to content

Commit 7960abd

Browse files
authored
[JUnit Platform Engine] Use number-and-pickle-if-parameterized strategy (#3004)
Given a feature with parameterized and unparameterized examples: ```feature Feature: Examples Tables Scenario Outline: Eating cucumbers Given there are <start> cucumbers When I eat <eat> cucumbers Then I should have <left> cucumbers Examples: These are passing | start | eat | left | | 12 | 5 | 7 | | 20 | 5 | 15 | Examples: These are failing | start | eat | left | | 12 | 20 | 0 | | 0 | 1 | 0 | Scenario Outline: Eating <color> cucumbers Given I am transparent When I eat <color> cucumbers Then I become <color> Examples: | color | | red | | green | | blue | ``` When the scenario name is parameterized, instead of only numbering the examples, the interpolated scenario name is also included. ``` Examples Tables - Eating cucumbers - These are passing - Example #1.1 - Example #1.2 - These are failing - Eating <color> cucumbers - Examples - Example #1.1: Eating red cucumbers - Example #1.2: Eating green cucumbers - Example #1.3: Eating blue cucumbers ```
1 parent ba8ce7b commit 7960abd

File tree

5 files changed

+103
-29
lines changed

5 files changed

+103
-29
lines changed

cucumber-junit-platform-engine/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,13 +420,13 @@ cucumber.junit-platform.naming-strategy= # long or short.
420420
# default: short
421421
# include parent descriptor name in test descriptor.
422422
423-
cucumber.junit-platform.naming-strategy.short.example-name= # number or pickle.
424-
# default: number
423+
cucumber.junit-platform.naming-strategy.short.example-name= # number, number-and-pickle-if-parameterized or pickle.
424+
# default: number-and-pickle-if-parameterized
425425
# Use example number or pickle name for examples when
426426
# short naming strategy is used
427427
428-
cucumber.junit-platform.naming-strategy.long.example-name= # number or pickle.
429-
# default: number
428+
cucumber.junit-platform.naming-strategy.long.example-name= # number, number-and-pickle-if-parameterized or pickle.
429+
# default: number-and-pickle-if-parameterized
430430
# Use example number or pickle name for examples when
431431
# long naming strategy is used
432432

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

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -143,17 +143,19 @@ public final class Constants {
143143
* Property name used to configure the naming strategy of examples in case
144144
* of short naming strategy: {@value}
145145
* <p>
146-
* Value must be one of {@code number} or {@code pickle}. By default,
147-
* numbers are used.
148-
* <p>
149-
* When set to {@code pickle} the pickle name is used. So for scenario name
150-
* {@code Adding <a> and <b>} and example with params {@code a = 10} and
151-
* {@code b = 20} the following name would be produced:
146+
* Value must be one of {@code number}, {@code pickle}, or
147+
* {@code number-and-pickle-if-parameterized}. By default,
148+
* {@code number-and-pickle-if-parameterized} is used.
149+
* <ul>
150+
* <li>When set to {@code number} examples are numbered. So the first
151+
* example of the first examples section would be named {@code #1.1}
152+
* <li>When set to {@code pickle} the pickle name is used. So for scenario
153+
* name {@code Adding <a> and <b>} and example with params {@code a = 10}
154+
* and {@code b = 20} the following name would be produced:
152155
* {@code Adding 10 and 20}.
153-
* <p>
154-
* Using example numbers works well in all scenarios, but if parameterized
155-
* scenario names are used consistently, the pickle name provides more
156-
* clarity.
156+
* <li>When set to {@code number-and-pickle-if-parameterized} the name would
157+
* be rendered as {@code #1.1: Adding 10 and 20}.
158+
* </ul>
157159
*/
158160
@API(status = Status.EXPERIMENTAL, since = "7.16.2")
159161
public static final String JUNIT_PLATFORM_SHORT_NAMING_STRATEGY_EXAMPLE_NAME_PROPERTY_NAME = "cucumber.junit-platform.naming-strategy.short.example-name";
@@ -162,17 +164,19 @@ public final class Constants {
162164
* Property name used to configure the naming strategy of examples in case
163165
* of long naming strategy: {@value}
164166
* <p>
165-
* Value must be one of {@code number} or {@code pickle}. By default,
166-
* numbers are used.
167-
* <p>
168-
* When set to {@code pickle} the pickle name is used. So for scenario name
169-
* {@code Adding <a> and <b>} and example with params {@code a = 10} and
170-
* {@code b = 20} the following name would be produced:
171-
* {@code Feature Name - Rule Name - Adding <a> and <b> - Examples Name - Adding 10 and 20}.
172-
* <p>
173-
* Using example numbers works well in all scenarios, but if parameterized
174-
* scenario names are used consistently, the pickle name provides more
175-
* clarity.
167+
* Value must be one of {@code number}, {@code pickle}, or
168+
* {@code number-and-pickle-if-parameterized}. By default,
169+
* {@code number-and-pickle-if-parameterized} is used.
170+
* <ul>
171+
* <li>When set to {@code number} examples are numbered. So the first
172+
* example of the first examples section would be named {@code #1.1}
173+
* <li>When set to {@code pickle} the pickle name is used. So for scenario
174+
* name {@code Adding <a> and <b>} and example with params {@code a = 10}
175+
* and {@code b = 20} the following name would be produced:
176+
* {@code Adding 10 and 20}.
177+
* <li>When set to {@code number-and-pickle-if-parameterized} the name would
178+
* be rendered as {@code #1.1: Adding 10 and 20}.
179+
* </ul>
176180
*/
177181
@API(status = Status.EXPERIMENTAL, since = "7.16.2")
178182
public static final String JUNIT_PLATFORM_LONG_NAMING_STRATEGY_EXAMPLE_NAME_PROPERTY_NAME = "cucumber.junit-platform.naming-strategy.long.example-name";

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ enum DefaultNamingStrategyProvider {
1818
NamingStrategy create(ConfigurationParameters configuration) {
1919
return configuration.get(JUNIT_PLATFORM_LONG_NAMING_STRATEGY_EXAMPLE_NAME_PROPERTY_NAME)
2020
.map(DefaultNamingStrategyProvider::parseStrategy)
21-
.orElse(DefaultNamingStrategyProvider::exampleNumberStrategy)
21+
.orElse(DefaultNamingStrategyProvider::exampleNumberAndPickleIfParameterizedStrategy)
2222
.apply(DefaultNamingStrategyProvider::longStrategy);
2323
}
2424
},
@@ -28,7 +28,7 @@ NamingStrategy create(ConfigurationParameters configuration) {
2828
NamingStrategy create(ConfigurationParameters configuration) {
2929
return configuration.get(JUNIT_PLATFORM_SHORT_NAMING_STRATEGY_EXAMPLE_NAME_PROPERTY_NAME)
3030
.map(DefaultNamingStrategyProvider::parseStrategy)
31-
.orElse(DefaultNamingStrategyProvider::exampleNumberStrategy)
31+
.orElse(DefaultNamingStrategyProvider::exampleNumberAndPickleIfParameterizedStrategy)
3232
.apply(DefaultNamingStrategyProvider::shortStrategy);
3333
}
3434
};
@@ -43,13 +43,38 @@ private static Function<BiFunction<Node, String, String>, NamingStrategy> parseS
4343
switch (exampleStrategy) {
4444
case "number":
4545
return DefaultNamingStrategyProvider::exampleNumberStrategy;
46+
case "number-and-pickle-if-parameterized":
47+
return DefaultNamingStrategyProvider::exampleNumberAndPickleIfParameterizedStrategy;
4648
case "pickle":
4749
return DefaultNamingStrategyProvider::pickleNameStrategy;
4850
default:
4951
throw new IllegalArgumentException("Unrecognized example naming strategy " + exampleStrategy);
5052
}
5153
}
5254

55+
private static NamingStrategy exampleNumberAndPickleIfParameterizedStrategy(
56+
BiFunction<Node, String, String> baseStrategy
57+
) {
58+
return createNamingStrategy(
59+
(node) -> baseStrategy.apply(node, nameOrKeyword(node)),
60+
(node, pickle) -> baseStrategy.apply(node, nameOrKeyword(node) + pickleNameIfParameterized(node, pickle)));
61+
}
62+
63+
private static String pickleNameIfParameterized(Node node, Pickle pickle) {
64+
if (node instanceof Node.Example) {
65+
String pickleName = pickle.getName();
66+
boolean parameterized = !node.getParent()
67+
.flatMap(Node::getParent)
68+
.flatMap(Node::getName)
69+
.filter(pickleName::equals)
70+
.isPresent();
71+
if (parameterized) {
72+
return ": " + pickleName;
73+
}
74+
}
75+
return "";
76+
}
77+
5378
private static NamingStrategy exampleNumberStrategy(BiFunction<Node, String, String> baseStrategy) {
5479
return createNamingStrategy(
5580
(node) -> baseStrategy.apply(node, nameOrKeyword(node)),

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@ private TestDescriptor getOutline() {
130130
return iterator.next();
131131
}
132132

133+
private TestDescriptor getParameterizedOutline() {
134+
Iterator<? extends TestDescriptor> iterator = getFeature().getChildren().iterator();
135+
iterator.next();
136+
iterator.next();
137+
iterator.next();
138+
return iterator.next();
139+
}
140+
133141
@Test
134142
void example() {
135143
TestDescriptor example = getExample();
@@ -153,8 +161,9 @@ void example() {
153161

154162
@Test
155163
void longNames() {
156-
configurationParameters = new MapConfigurationParameters(
157-
JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, "long");
164+
configurationParameters = new MapConfigurationParameters(Map.of(
165+
JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, "long",
166+
JUNIT_PLATFORM_LONG_NAMING_STRATEGY_EXAMPLE_NAME_PROPERTY_NAME, "number"));
158167

159168
TestDescriptor example = getExample();
160169
assertEquals("A feature with scenario outlines - A scenario outline - With some text - Example #1.1",
@@ -172,6 +181,17 @@ void longNamesWithPickleNames() {
172181
example.getDisplayName());
173182
}
174183

184+
@Test
185+
void longNamesWithPickleNamesIfParameterized() {
186+
configurationParameters = new MapConfigurationParameters(
187+
JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, "long");
188+
189+
TestDescriptor example = getParametrizedExample();
190+
assertEquals(
191+
"A feature with scenario outlines - A scenario with <example> - Examples - Example #1.1: A scenario with A",
192+
example.getDisplayName());
193+
}
194+
175195
@Test
176196
void shortNamesWithExampleNumbers() {
177197
configurationParameters = new MapConfigurationParameters(
@@ -191,10 +211,23 @@ void shortNamesWithPickleNames() {
191211
assertEquals("A scenario outline", example.getDisplayName());
192212
}
193213

214+
@Test
215+
void shortNamesWithPickleNamesIfParameterized() {
216+
configurationParameters = new MapConfigurationParameters(
217+
JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, "short");
218+
219+
TestDescriptor example = getParametrizedExample();
220+
assertEquals("Example #1.1: A scenario with A", example.getDisplayName());
221+
}
222+
194223
private TestDescriptor getExample() {
195224
return getOutline().getChildren().iterator().next().getChildren().iterator().next();
196225
}
197226

227+
private TestDescriptor getParametrizedExample() {
228+
return getParameterizedOutline().getChildren().iterator().next().getChildren().iterator().next();
229+
}
230+
198231
@Test
199232
void parallelExecutionForFeaturesEnabled() {
200233
configurationParameters = new MapConfigurationParameters(

cucumber-junit-platform-engine/src/test/resources/io/cucumber/junit/platform/engine/feature-with-outline.feature

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,15 @@ Feature: A feature with scenario outlines
3636
| example |
3737
| A |
3838
| B |
39+
40+
@ScenarioOutlineTag
41+
Scenario Outline: A scenario with <example>
42+
Given a parameterized scenario outline
43+
When it is executed
44+
Then <example> is used
45+
46+
@Example1Tag
47+
Examples:
48+
| example |
49+
| A |
50+
| B |

0 commit comments

Comments
 (0)