From 41a3d5c65a823412c764c9987c3e5e1f2e1521a8 Mon Sep 17 00:00:00 2001 From: iTitou Date: Wed, 27 Oct 2021 14:41:34 +0200 Subject: [PATCH 1/2] Show individual pass/fail per steps and highlight first failing step Signed-off-by: iTitou --- pytest_bdd/gherkin_terminal_reporter.py | 50 ++++++++++--------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/pytest_bdd/gherkin_terminal_reporter.py b/pytest_bdd/gherkin_terminal_reporter.py index 3e3623bb..76b90fd9 100644 --- a/pytest_bdd/gherkin_terminal_reporter.py +++ b/pytest_bdd/gherkin_terminal_reporter.py @@ -54,37 +54,25 @@ def pytest_runtest_logreport(self, report): word_markup = {"red": True} elif rep.skipped: word_markup = {"yellow": True} - feature_markup = {"blue": True} scenario_markup = word_markup - if self.verbosity <= 0: - return super().pytest_runtest_logreport(rep) - elif self.verbosity == 1: - if hasattr(report, "scenario"): - self.ensure_newline() - self._tw.write("Feature: ", **feature_markup) - self._tw.write(report.scenario["feature"]["name"], **feature_markup) - self._tw.write("\n") - self._tw.write(" Scenario: ", **scenario_markup) - self._tw.write(report.scenario["name"], **scenario_markup) - self._tw.write(" ") - self._tw.write(word, **word_markup) - self._tw.write("\n") - else: - return super().pytest_runtest_logreport(rep) - elif self.verbosity > 1: - if hasattr(report, "scenario"): - self.ensure_newline() - self._tw.write("Feature: ", **feature_markup) - self._tw.write(report.scenario["feature"]["name"], **feature_markup) - self._tw.write("\n") - self._tw.write(" Scenario: ", **scenario_markup) - self._tw.write(report.scenario["name"], **scenario_markup) - self._tw.write("\n") - for step in report.scenario["steps"]: - self._tw.write(f" {step['keyword']} {step['name']}\n", **scenario_markup) - self._tw.write(" " + word, **word_markup) - self._tw.write("\n\n") - else: - return super().pytest_runtest_logreport(rep) + if self.verbosity <= 0 or not hasattr(report, "scenario"): + return super().pytest_runtest_logreport(report) + + scenario = report.scenario + self.ensure_newline() + self._tw.write(f"Feature: {scenario['feature']['name']}\n", blue=True) + self._tw.write(f" Scenario: {scenario['name']}", **scenario_markup) + if self.verbosity > 1: + self._tw.write("\n") + has_already_failed = False + for step in scenario["steps"]: + step_markup = {"red" if step["failed"] else "green": True} + # Highlight first failed step + if step["failed"] and not has_already_failed: + step_markup["bold"] = True + has_already_failed = True + step_status_text = "(FAILED)" if step["failed"] else "(PASSED)" + self._tw.write(f" {step['keyword']} {step['name']} {step_status_text}\n", **step_markup) + self._tw.write(f" {word}\n", **word_markup) self.stats.setdefault(cat, []).append(rep) From 350a3b41b54dac2c116fa0857fc2dcd9aa35219f Mon Sep 17 00:00:00 2001 From: iTitou Date: Wed, 27 Oct 2021 15:48:42 +0200 Subject: [PATCH 2/2] Adapt tests Signed-off-by: iTitou --- tests/feature/test_gherkin_terminal_reporter.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/feature/test_gherkin_terminal_reporter.py b/tests/feature/test_gherkin_terminal_reporter.py index 52946bfe..788639ed 100644 --- a/tests/feature/test_gherkin_terminal_reporter.py +++ b/tests/feature/test_gherkin_terminal_reporter.py @@ -55,7 +55,7 @@ def test_verbose_mode_should_display_feature_and_scenario_names_instead_of_test_ result = testdir.runpytest("--gherkin-terminal-reporter", "-v") result.assert_outcomes(passed=1, failed=0) result.stdout.fnmatch_lines("Feature: Gherkin terminal output feature") - result.stdout.fnmatch_lines("*Scenario: Scenario example 1 PASSED") + result.stdout.fnmatch_lines("*Scenario: Scenario example 1 PASSED") def test_verbose_mode_should_preserve_displaying_regular_tests_as_usual(testdir): @@ -85,9 +85,9 @@ def test_double_verbose_mode_should_display_full_scenario_description(testdir): result.assert_outcomes(passed=1, failed=0) result.stdout.fnmatch_lines("*Scenario: Scenario example 1") - result.stdout.fnmatch_lines("*Given there is a bar") - result.stdout.fnmatch_lines("*When the bar is accessed") - result.stdout.fnmatch_lines("*Then world explodes") + result.stdout.fnmatch_lines("*Given there is a bar (PASSED)") + result.stdout.fnmatch_lines("*When the bar is accessed (PASSED)") + result.stdout.fnmatch_lines("*Then world explodes (PASSED)") result.stdout.fnmatch_lines("*PASSED") @@ -228,7 +228,7 @@ def test_scenario_2(): result = testdir.runpytest("--gherkin-terminal-reporter", "-vv") result.assert_outcomes(passed=1, failed=0) result.stdout.fnmatch_lines("*Scenario: Scenario example 2") - result.stdout.fnmatch_lines("*Given there are {start} cucumbers".format(**example)) - result.stdout.fnmatch_lines("*When I eat {eat} cucumbers".format(**example)) - result.stdout.fnmatch_lines("*Then I should have {left} cucumbers".format(**example)) + result.stdout.fnmatch_lines("*Given there are {start} cucumbers (PASSED)".format(**example)) + result.stdout.fnmatch_lines("*When I eat {eat} cucumbers (PASSED)".format(**example)) + result.stdout.fnmatch_lines("*Then I should have {left} cucumbers (PASSED)".format(**example)) result.stdout.fnmatch_lines("*PASSED")