diff --git a/allure-cucumber7-jvm/src/main/java/io/qameta/allure/cucumber7jvm/AllureCucumber7Jvm.java b/allure-cucumber7-jvm/src/main/java/io/qameta/allure/cucumber7jvm/AllureCucumber7Jvm.java index 886c9797c..1cbf12b14 100644 --- a/allure-cucumber7-jvm/src/main/java/io/qameta/allure/cucumber7jvm/AllureCucumber7Jvm.java +++ b/allure-cucumber7-jvm/src/main/java/io/qameta/allure/cucumber7jvm/AllureCucumber7Jvm.java @@ -98,6 +98,7 @@ public class AllureCucumber7Jvm implements ConcurrentEventListener { private static final String CSV_ESCAPED_QUOTE = CSV_QUOTE + CSV_QUOTE; private static final String NEW_LINE = "\n"; private static final String CARRIAGE_RETURN = "\r"; + private static final String UNDEFINED_STEP_MESSAGE = "Undefined Step. Please add step definition"; private final AllureLifecycle lifecycle; @@ -254,8 +255,7 @@ private void handleTestCaseFinished(final TestCaseFinished event) { final String uuid = testCase.getId().toString(); final Result result = event.getResult(); final Status status = translateTestCaseStatus(result); - final StatusDetails statusDetails = getStatusDetails(result.getError()) - .orElseGet(StatusDetails::new); + final StatusDetails statusDetails = translateStatusDetails(result); final TagParser tagParser = new TagParser(feature, testCase); statusDetails @@ -415,13 +415,22 @@ private Status translateTestCaseStatus(final Result testCaseResult) { case SKIPPED: case PENDING: return Status.SKIPPED; - case AMBIGUOUS: case UNDEFINED: + return Status.BROKEN; + case AMBIGUOUS: default: return null; } } + private StatusDetails translateStatusDetails(final Result result) { + if (result.getStatus() == io.cucumber.plugin.event.Status.UNDEFINED) { + return new StatusDetails().setMessage(UNDEFINED_STEP_MESSAGE); + } + return getStatusDetails(result.getError()) + .orElseGet(StatusDetails::new); + } + private List getExamplesAsParameters( final Scenario scenario, final TestCase localCurrentTestCase) { @@ -537,10 +546,7 @@ private void handleStopStep(final TestCase testCase, final Status stepStatus = translateTestCaseStatus(eventResult); - final StatusDetails statusDetails = eventResult.getStatus() == io.cucumber.plugin.event.Status.UNDEFINED - ? new StatusDetails().setMessage("Undefined Step. Please add step definition") - : getStatusDetails(eventResult.getError()) - .orElse(new StatusDetails()); + final StatusDetails statusDetails = translateStatusDetails(eventResult); final TagParser tagParser = new TagParser(feature, testCase); statusDetails diff --git a/allure-cucumber7-jvm/src/test/java/io/qameta/allure/cucumber7jvm/AllureCucumber7JvmTest.java b/allure-cucumber7-jvm/src/test/java/io/qameta/allure/cucumber7jvm/AllureCucumber7JvmTest.java index 5c4fd2253..650df75c9 100644 --- a/allure-cucumber7-jvm/src/test/java/io/qameta/allure/cucumber7jvm/AllureCucumber7JvmTest.java +++ b/allure-cucumber7-jvm/src/test/java/io/qameta/allure/cucumber7jvm/AllureCucumber7JvmTest.java @@ -74,6 +74,7 @@ class AllureCucumber7JvmTest { private static final String EXPECTED_CUCUMBER_VERSION_PROPERTY = "allure.test.cucumber.version"; + private static final String UNDEFINED_STEP_MESSAGE = "Undefined Step. Please add step definition"; @AllureFeatures.Base @Test @@ -496,8 +497,13 @@ void shouldAddCommonLabels() { .doesNotContain(TEST_CLASS_LABEL_NAME, TEST_METHOD_LABEL_NAME); } + /** + * An undefined step breaks the scenario and carries a useful explanation; later steps stay skipped. + */ + @AllureFeatures.BrokenTests @AllureFeatures.Steps @Test + @Description void shouldProcessUndefinedSteps() { final AllureResults results = runFeature("features/undefined.feature"); @@ -505,16 +511,55 @@ void shouldProcessUndefinedSteps() { assertThat(testResults) .extracting(TestResult::getName, TestResult::getStatus) .containsExactlyInAnyOrder( - tuple("Step is not defined", null) + tuple("Step is not defined", Status.BROKEN) ); - assertThat(testResults.get(0).getSteps()) + final TestResult testResult = testResults.get(0); + assertThat(testResult.getStatusDetails().getMessage()) + .isEqualTo(UNDEFINED_STEP_MESSAGE); + + final List steps = testResult.getSteps(); + assertThat(steps) .extracting(StepResult::getName, StepResult::getStatus) - .containsExactlyInAnyOrder( + .containsExactly( tuple("Given a is 5", Status.PASSED), - tuple("When step is undefined", null), + tuple("When step is undefined", Status.BROKEN), tuple("Then b is 10", Status.SKIPPED) ); + assertThat(steps.get(1).getStatusDetails().getMessage()) + .isEqualTo(UNDEFINED_STEP_MESSAGE); + } + + /** + * An undefined final step still breaks both the step and its scenario. + */ + @AllureFeatures.BrokenTests + @AllureFeatures.Steps + @Test + @Description + void shouldProcessUndefinedLastStep() { + final AllureResults results = runFeature("features/undefined-last.feature"); + + final List testResults = results.getTestResults(); + assertThat(testResults) + .extracting(TestResult::getName, TestResult::getStatus) + .containsExactlyInAnyOrder( + tuple("Last step is not defined", Status.BROKEN) + ); + + final TestResult testResult = testResults.get(0); + assertThat(testResult.getStatusDetails().getMessage()) + .isEqualTo(UNDEFINED_STEP_MESSAGE); + + final List steps = testResult.getSteps(); + assertThat(steps) + .extracting(StepResult::getName, StepResult::getStatus) + .containsExactly( + tuple("Given a is 5", Status.PASSED), + tuple("When step is undefined", Status.BROKEN) + ); + assertThat(steps.get(1).getStatusDetails().getMessage()) + .isEqualTo(UNDEFINED_STEP_MESSAGE); } @AllureFeatures.SkippedTests diff --git a/allure-cucumber7-jvm/src/test/resources/features/undefined-last.feature b/allure-cucumber7-jvm/src/test/resources/features/undefined-last.feature new file mode 100644 index 000000000..2e518889b --- /dev/null +++ b/allure-cucumber7-jvm/src/test/resources/features/undefined-last.feature @@ -0,0 +1,5 @@ +Feature: Simple feature with an undefined last step + + Scenario: Last step is not defined + Given a is 5 + When step is undefined