diff --git a/src/main/java/com/thoughtworks/gauge/execution/HooksExecutor.java b/src/main/java/com/thoughtworks/gauge/execution/HooksExecutor.java index b6636796..9d6e67e6 100644 --- a/src/main/java/com/thoughtworks/gauge/execution/HooksExecutor.java +++ b/src/main/java/com/thoughtworks/gauge/execution/HooksExecutor.java @@ -34,7 +34,7 @@ public Spec.ProtoExecutionResult execute() { for (Hook hook : hooks) { result = new TaggedHookExecutor(hook, info).execute(); totalHooksExecutionTime += result.getExecutionTime(); - if (result.getFailed()) { + if (result.getFailed() || result.getSkipScenario()) { return Spec.ProtoExecutionResult.newBuilder(result).setExecutionTime(totalHooksExecutionTime).build(); } } diff --git a/src/main/java/com/thoughtworks/gauge/execution/StepExecutionStage.java b/src/main/java/com/thoughtworks/gauge/execution/StepExecutionStage.java index 32b693f7..39f05164 100644 --- a/src/main/java/com/thoughtworks/gauge/execution/StepExecutionStage.java +++ b/src/main/java/com/thoughtworks/gauge/execution/StepExecutionStage.java @@ -35,7 +35,7 @@ public void setNextStage(ExecutionStage stage) { } public Spec.ProtoExecutionResult execute(Spec.ProtoExecutionResult previousStageResult) { - if (previousStageResult.getFailed()) { + if (previousStageResult.getFailed() || previousStageResult.getSkipScenario()) { return executeNext(previousStageResult); } Spec.ProtoExecutionResult stageResult = executeStep(); diff --git a/src/test/java/com/thoughtworks/gauge/execution/HooksExecutorTest.java b/src/test/java/com/thoughtworks/gauge/execution/HooksExecutorTest.java index 54c2cc39..bd096131 100644 --- a/src/test/java/com/thoughtworks/gauge/execution/HooksExecutorTest.java +++ b/src/test/java/com/thoughtworks/gauge/execution/HooksExecutorTest.java @@ -8,14 +8,18 @@ import com.thoughtworks.gauge.BeforeScenario; import com.thoughtworks.gauge.ClassInstanceManager; import com.thoughtworks.gauge.ContinueOnFailure; +import com.thoughtworks.gauge.ExecutionContext; import com.thoughtworks.gauge.Operator; +import com.thoughtworks.gauge.SkipScenarioException; import com.thoughtworks.gauge.hook.Hook; import gauge.messages.Spec; import org.junit.jupiter.api.Test; import java.util.ArrayList; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; public class HooksExecutorTest { @@ -30,6 +34,25 @@ public void testHookExecutor() throws Exception { assertFalse(result.getRecoverableError()); } + @Test + public void shouldShortCircuitOnSkipScenario() throws Exception { + Hook skipHook = new Hook(HooksExecutorTest.class.getMethod("hookThatSkips"), new String[0], Operator.AND); + Hook shouldNotRunHook = new Hook(HooksExecutorTest.class.getMethod("hookThatFails"), new String[0], Operator.AND); + HooksExecutor executor = new HooksExecutor( + List.of(skipHook, shouldNotRunHook), new ExecutionContext(), new ClassInstanceManager()); + Spec.ProtoExecutionResult result = executor.execute(); + assertTrue(result.getSkipScenario()); + assertFalse(result.getFailed()); + } + + public void hookThatSkips() { + throw new SkipScenarioException("skip this scenario"); + } + + public void hookThatFails() { + throw new RuntimeException("second hook must not run after skip"); + } + private static class TestHook { @ContinueOnFailure @BeforeScenario diff --git a/src/test/java/com/thoughtworks/gauge/execution/StepExecutionStageTest.java b/src/test/java/com/thoughtworks/gauge/execution/StepExecutionStageTest.java index cd4707c1..3c8acb0a 100644 --- a/src/test/java/com/thoughtworks/gauge/execution/StepExecutionStageTest.java +++ b/src/test/java/com/thoughtworks/gauge/execution/StepExecutionStageTest.java @@ -252,4 +252,18 @@ public Object table(Object table) { public void skipScenarioStep() { throw new SkipScenarioException("skipping this scenario due to unmet condition"); } + + @Test + public void shouldShortCircuitIfPreviousStageSkipped() { + Messages.ExecuteStepRequest executeStepRequest = Messages.ExecuteStepRequest.newBuilder() + .setParsedStepText("foo bar") + .setActualStepText("foo bar") + .build(); + StepExecutionStage executionStage = new StepExecutionStage( + executeStepRequest, new ClassInstanceManager(), new ParameterParsingChain(), mock(StepRegistry.class) + ); + Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setSkipScenario(true).build(); + Spec.ProtoExecutionResult result = executionStage.execute(previous); + assertTrue(result.getSkipScenario()); + } }