Skip to content
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

[Core] Add property to skip execution of tagged scenarios #2952

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public final class Constants {
* <p>
* Limits the number of scenarios to be executed to a specific amount.
* <p>
* By default scenarios are executed.
* By default, scenarios are executed.
*/
public static final String EXECUTION_LIMIT_PROPERTY_NAME = "cucumber.execution.limit";

Expand All @@ -42,10 +42,12 @@ 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
*/
public static final String EXECUTION_ORDER_PROPERTY_NAME = "cucumber.execution.order";

public static final String EXECUTION_SKIP_TAGS_PROPERTY_NAME = "cucumber.execution.skip.tags";

/**
* Property name used to enable wip execution: {@value}
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public final class RuntimeOptions implements
// For context see: https://mattwynne.net/new-beginning
private boolean publishQuiet = true;
private boolean enablePublishPlugin;
private List<Expression> skipTagExpressions = new ArrayList<>();

private RuntimeOptions() {

Expand Down Expand Up @@ -174,6 +175,11 @@ public Class<? extends UuidGenerator> getUuidGeneratorClass() {
return uuidGeneratorClass;
}

@Override
public List<Expression> getSkipTagExpressions() {
return skipTagExpressions;
}

void setUuidGeneratorClass(Class<? extends UuidGenerator> uuidGeneratorClass) {
this.uuidGeneratorClass = uuidGeneratorClass;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.cucumber.core.backend.ObjectFactory;
import io.cucumber.core.eventbus.UuidGenerator;
import io.cucumber.core.snippets.SnippetType;
import io.cucumber.tagexpressions.Expression;

import java.net.URI;
import java.util.List;
Expand All @@ -19,4 +20,6 @@ public interface Options {

Class<? extends UuidGenerator> getUuidGeneratorClass();

List<Expression> getSkipTagExpressions();

}
20 changes: 17 additions & 3 deletions cucumber-core/src/main/java/io/cucumber/core/runner/Runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.cucumber.plugin.event.Location;
import io.cucumber.plugin.event.SnippetsSuggestedEvent;
import io.cucumber.plugin.event.SnippetsSuggestedEvent.Suggestion;
import io.cucumber.tagexpressions.Expression;

import java.net.URI;
import java.util.ArrayList;
Expand Down Expand Up @@ -138,15 +139,28 @@ private void buildBackendWorlds() {
}

private TestCase createTestCaseForPickle(Pickle pickle) {
ExecutionMode executionMode = getExecutionMode(pickle);

if (pickle.getSteps().isEmpty()) {
return new TestCase(bus.generateId(), emptyList(), emptyList(), emptyList(), pickle,
runnerOptions.isDryRun());
return new TestCase(bus.generateId(), emptyList(), emptyList(), emptyList(), pickle, executionMode);
}

List<PickleStepTestStep> testSteps = createTestStepsForPickleSteps(pickle);
List<HookTestStep> beforeHooks = createTestStepsForBeforeHooks(pickle.getTags());
List<HookTestStep> afterHooks = createTestStepsForAfterHooks(pickle.getTags());
return new TestCase(bus.generateId(), testSteps, beforeHooks, afterHooks, pickle, runnerOptions.isDryRun());
return new TestCase(bus.generateId(), testSteps, beforeHooks, afterHooks, pickle, executionMode);
}

private ExecutionMode getExecutionMode(Pickle pickle) {
List<Expression> skipTagExpression = runnerOptions.getSkipTagExpressions();
if (!skipTagExpression.isEmpty()
&& skipTagExpression.stream().allMatch(expression -> expression.evaluate(pickle.getTags()))) {
return ExecutionMode.SKIP;
} else if (runnerOptions.isDryRun()) {
return ExecutionMode.DRY_RUN;
} else {
return ExecutionMode.RUN;
}
}

private void disposeBackendWorlds() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import java.util.UUID;
import java.util.stream.Collectors;

import static io.cucumber.core.runner.ExecutionMode.DRY_RUN;
import static io.cucumber.core.runner.ExecutionMode.RUN;
import static io.cucumber.messages.Convertor.toMessage;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
Expand All @@ -42,14 +40,14 @@ final class TestCase implements io.cucumber.plugin.event.TestCase {
List<HookTestStep> beforeHooks,
List<HookTestStep> afterHooks,
Pickle pickle,
boolean dryRun
ExecutionMode executionMode
) {
this.id = id;
this.testSteps = testSteps;
this.beforeHooks = beforeHooks;
this.afterHooks = afterHooks;
this.pickle = pickle;
this.executionMode = dryRun ? DRY_RUN : RUN;
this.executionMode = executionMode;
}

private static io.cucumber.messages.types.Group makeMessageGroup(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class HookTestStepTest {
Collections.emptyList(),
Collections.emptyList(),
feature.getPickles().get(0),
false);
ExecutionMode.RUN);
private final EventBus bus = mock(EventBus.class);
private final UUID testExecutionId = UUID.randomUUID();
private final TestCaseState state = new TestCaseState(bus, testExecutionId, testCase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class PickleStepTestStepTest {
" Given I have 4 cukes in my belly\n");
private final Pickle pickle = feature.getPickles().get(0);
private final TestCase testCase = new TestCase(UUID.randomUUID(), Collections.emptyList(), Collections.emptyList(),
Collections.emptyList(), pickle, false);
Collections.emptyList(), pickle, ExecutionMode.RUN);
private final EventBus bus = mock(EventBus.class);
private final UUID testExecutionId = UUID.randomUUID();
private final TestCaseState state = new TestCaseState(bus, testExecutionId, testCase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class TestCaseStateResultTest {
Collections.emptyList(),
Collections.emptyList(),
feature.getPickles().get(0),
false));
ExecutionMode.RUN));

@BeforeEach
void setup() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private TestCaseState createTestCaseState(Feature feature) {
Collections.emptyList(),
Collections.emptyList(),
feature.getPickles().get(0),
false));
ExecutionMode.RUN));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void run_wraps_execute_in_test_case_started_and_finished_events() throws Throwab

private TestCase createTestCase(PickleStepTestStep... steps) {
return new TestCase(UUID.randomUUID(), asList(steps), Collections.emptyList(), Collections.emptyList(),
pickle(), false);
pickle(), ExecutionMode.RUN);
}

private Pickle pickle() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public final class Constants {
*/
public static final String EXECUTION_DRY_RUN_PROPERTY_NAME = io.cucumber.core.options.Constants.EXECUTION_DRY_RUN_PROPERTY_NAME;

public static final String EXECUTION_SKIP_TAGS_PROPERTY_NAME = io.cucumber.core.options.Constants.EXECUTION_SKIP_TAGS_PROPERTY_NAME;

/**
* Tag replacement pattern for the exclusive resource templates: {@value}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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.EXECUTION_SKIP_TAGS_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.FEATURES_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;
Expand All @@ -41,6 +42,7 @@
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 java.util.Collections.emptyList;

class CucumberEngineOptions implements
io.cucumber.core.plugin.Options,
Expand Down Expand Up @@ -164,6 +166,14 @@ public Class<? extends UuidGenerator> getUuidGeneratorClass() {
.orElse(null);
}

@Override
public List<Expression> getSkipTagExpressions() {
return configurationParameters
.get(EXECUTION_SKIP_TAGS_PROPERTY_NAME, TagExpressionParser::parse)
.map(Collections::singletonList)
.orElse(emptyList());
}

boolean isParallelExecutionEnabled() {
return configurationParameters
.getBoolean(PARALLEL_EXECUTION_ENABLED_PROPERTY_NAME)
Expand All @@ -185,6 +195,6 @@ List<FeatureWithLines> featuresWithLines() {
.sorted(Comparator.comparing(FeatureWithLines::uri))
.distinct()
.collect(Collectors.toList()))
.orElse(Collections.emptyList());
.orElse(emptyList());
}
}
Loading