From 620a41ec409072ad8943324cb8b764e518b73b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czy=C5=BC?= Date: Thu, 17 Sep 2015 00:09:10 +0100 Subject: [PATCH 1/5] ISSUE-139 add gherkin terminal reporter --- pytest_bdd/gherkin_terminal_reporter.py | 99 +++++++ pytest_bdd/plugin.py | 3 + .../feature/gherkin_terminal_reporter.feature | 42 +++ .../feature/test_gherkin_terminal_reporter.py | 279 ++++++++++++++++++ 4 files changed, 423 insertions(+) create mode 100644 pytest_bdd/gherkin_terminal_reporter.py create mode 100644 tests/feature/gherkin_terminal_reporter.feature create mode 100644 tests/feature/test_gherkin_terminal_reporter.py diff --git a/pytest_bdd/gherkin_terminal_reporter.py b/pytest_bdd/gherkin_terminal_reporter.py new file mode 100644 index 00000000..adf6b774 --- /dev/null +++ b/pytest_bdd/gherkin_terminal_reporter.py @@ -0,0 +1,99 @@ +# -*- encoding: utf-8 -*- +import py +import pytest + +from _pytest.terminal import TerminalReporter + + +def add_options(parser): + group = parser.getgroup("terminal reporting", "reporting", after="general") + group._addoption( + '--gherkin-terminal-reporter', + action="store_true", + dest="gherkin_terminal_reporter", + default=False, + help=( + "enable gherkin output" + ) + ) + + +@pytest.mark.trylast +def pytest_configure(config): + if config.option.gherkin_terminal_reporter: + # Get the standard terminal reporter plugin and replace it with our + current_reporter = config.pluginmanager.getplugin('terminalreporter') + if current_reporter.__class__ != TerminalReporter: + raise Exception("gherkin-terminal-reporter is not compatibile with any other terminal reporter." + "You can use only one terminal reporter." + "Currently '{0}' is used." + "Please decide to use one by deactivating {0} or gherkin-terminal-reporter." + .format(current_reporter.__class__)) + gherkin_reporter = GherkinTerminalReporter(config) + config.pluginmanager.unregister(current_reporter) + config.pluginmanager.register(gherkin_reporter, 'terminalreporter') + if config.pluginmanager.getplugin("dsession"): + raise Exception("gherkin-terminal-reporter is not compatible with 'xdist' plugin.") + + +class GherkinTerminalReporter(TerminalReporter): + def __init__(self, config): + TerminalReporter.__init__(self, config) + + def pytest_runtest_logstart(self, nodeid, location): + # Prevent locationline from being printed since we already + # show the module_name & in verbose mode the test name. + pass + + def pytest_runtest_logreport(self, report): + rep = report + res = self.config.hook.pytest_report_teststatus(report=rep) + cat, letter, word = res + self.stats.setdefault(cat, []).append(rep) + if not letter and not word: + # probably passed setup/teardown + return + + if isinstance(word, tuple): + word, word_markup = word + else: + if rep.passed: + word_markup = {'green': True} + elif rep.failed: + word_markup = {'red': True} + elif rep.skipped: + word_markup = {'yellow': True} + feature_markup = {'blue': True} + scenario_markup = word_markup + + if self.verbosity <= 0: + return TerminalReporter.pytest_runtest_logreport(self, 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 TerminalReporter.pytest_runtest_logreport(self, 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(' {} {}\n'.format(step['keyword'], + step['name']), **scenario_markup) + self._tw.write(' ' + word, **word_markup) + self._tw.write('\n\n') + else: + return TerminalReporter.pytest_runtest_logreport(self, rep) diff --git a/pytest_bdd/plugin.py b/pytest_bdd/plugin.py index 2827174a..08685790 100644 --- a/pytest_bdd/plugin.py +++ b/pytest_bdd/plugin.py @@ -5,12 +5,14 @@ from . import given, when, then from . import cucumber_json from . import generation +from . import gherkin_terminal_reporter # Import hook handlers: from .reporting import * from .cucumber_json import * from .generation import * +from .gherkin_terminal_reporter import * from .fixtures import * @@ -38,3 +40,4 @@ def pytest_addoption(parser): """Add pytest-bdd options.""" cucumber_json.add_options(parser) generation.add_options(parser) + gherkin_terminal_reporter.add_options(parser) diff --git a/tests/feature/gherkin_terminal_reporter.feature b/tests/feature/gherkin_terminal_reporter.feature new file mode 100644 index 00000000..2c1ecdeb --- /dev/null +++ b/tests/feature/gherkin_terminal_reporter.feature @@ -0,0 +1,42 @@ +Feature: Gherkin terminal reporter + + Scenario: Should default output be the same as regular terminal reporter + Given there is gherkin scenario implemented + When tests are run + Then output must be formatted the same way as regular one + + Scenario: Should verbose mode enable displaying feature and scenario names rather than test names in a single line + Given there is gherkin scenario implemented + When tests are run with verbose mode + Then output should contain single line feature description + And output should contain single line scenario description + + Scenario: Should verbose mode preserve displaying of regular tests as usual + Given there is non-gherkin scenario implemented + When tests are run with verbose mode + Then output must be formatted the same way as regular one + + Scenario: Should double verbose mode enable displaying of full gherkin scenario description + Given there is gherkin scenario implemented + When tests are run with very verbose mode + Then output must contain full gherkin scenario description + + Scenario: Should error message be displayed when no scenario is found + Given there is gherkin scenario without implementation + When tests are run with any verbosity mode + Then output contains error about missing scenario implementation + + Scenario: Should error message be displayed when no step is found + Given there is gherkin scenario partially implemented + When tests are run with any verbosity mode + Then output contains error about missing step implementation + + Scenario: Should error message be displayed when error occurs during test execution + Given there is gherkin scenario with broken implementation + When tests are run with any verbosity mode + Then output contains error about missing scenario implementation + + Scenario: Should local variables be displayed when --showlocals option is used + Given there is gherkin scenario with broken implementation + When tests are run with --showlocals + Then error traceback contains local variable descriptions diff --git a/tests/feature/test_gherkin_terminal_reporter.py b/tests/feature/test_gherkin_terminal_reporter.py new file mode 100644 index 00000000..8322be58 --- /dev/null +++ b/tests/feature/test_gherkin_terminal_reporter.py @@ -0,0 +1,279 @@ +import re + + +import pytest + +from pytest_bdd import scenario, scenarios, given, when, then +from pytest_bdd import exceptions + + +@scenario('gherkin_terminal_reporter.feature', + 'Should default output be the same as regular terminal reporter') +def test_Should_default_output_be_the_same_as_regular_terminal_reporter(): + pass + + +@scenario('gherkin_terminal_reporter.feature', + 'Should verbose mode enable displaying feature and scenario names rather than test names in a single line') +def test_Should_verbose_mode_enable_displaying_feature_and_scenario_names_rather_than_test_names_in_a_single_line(): + pass + + +@scenario('gherkin_terminal_reporter.feature', + 'Should verbose mode preserve displaying of regular tests as usual') +def test_Should_verbose_mode_preserve_displaying_of_regular_tests_as_usual(): + pass + + +@scenario('gherkin_terminal_reporter.feature', + 'Should double verbose mode enable displaying of full gherkin scenario description') +def test_Should_double_verbose_mode_enable_displaying_of_full_gherkin_scenario_description(): + pass + + +@scenario('gherkin_terminal_reporter.feature', + 'Should error message be displayed when no scenario is found') +def test_Should_error_message_be_displayed_when_no_scenario_is_found(verbosity_mode): + pass + + +@scenario('gherkin_terminal_reporter.feature', + 'Should error message be displayed when no step is found') +def test_Should_error_message_be_displayed_when_no_step_is_found(verbosity_mode): + pass + + +@scenario('gherkin_terminal_reporter.feature', + 'Should error message be displayed when error occurs during test execution') +def test_Should_error_message_be_displayed_when_error_occurs_during_test_execution(verbosity_mode): + pass + + +@scenario('gherkin_terminal_reporter.feature', + 'Should local variables be displayed when --showlocals option is used') +def test_Should_local_variables_be_displayed_when___showlocals_option_is_used(): + pass + + +@pytest.fixture(params=[0, 1, 2], + ids=['compact mode', 'line per test', 'verbose']) +def verbosity_mode(request): + return request.param, '-' + 'v' * request.param if request.param else '' + + +@pytest.fixture +def test_execution(): + return {} + + +@given("there is non-gherkin scenario implemented") +def non_gherkin_test(testdir): + testdir.makepyfile(test_regular=""" + def test_1(): + pass + """) + + +@given("there is gherkin scenario implemented") +def gherkin_scenario(testdir): + testdir.makefile('.feature', test=""" + Feature: Gherkin terminal output feature + Scenario: Scenario example 1 + Given there is a bar + When the bar is accessed + Then world explodes + """) + testdir.makepyfile(test_gherkin=""" + import pytest + from pytest_bdd import given, when, scenario, then + + @given('there is a bar') + def a_bar(): + return 'bar' + + @when('the bar is accessed') + def the_bar_is_accessed(): + pass + + @then('world explodes') + def world_explodes(): + pass + + @scenario('test.feature', 'Scenario example 1') + def test_scenario_1(): + pass + """) + + +@when("tests are run") +def tests_are_run(testdir, test_execution): + test_execution['regular'] = testdir.runpytest() + test_execution['gherkin'] = testdir.runpytest('--gherkin-terminal-reporter') + + +@then("output must be formatted the same way as regular one") +def output_must_be_the_same_as_regular_reporter(test_execution): + reg = test_execution['regular'] + ghe = test_execution['gherkin'] + assert reg.ret == 0 + assert ghe.ret == 0 + # last line can be different because of test execution time is printed + reg_lines = reg.stdout.lines if reg.stdout.lines[-1] else reg.stdout.lines[:-2] + reg_lines[-1] = re.sub(r' \d+\.\d+ ', ' X ', reg_lines[-1]) + ghe_lines = ghe.stdout.lines if ghe.stdout.lines[-1] else ghe.stdout.lines[:-2] + ghe_lines[-1] = re.sub(r' \d+\.\d+ ', ' X ', ghe_lines[-1]) + for l1, l2 in zip(reg_lines, ghe_lines): + assert l1 == l2 + + +@when("tests are run with verbose mode") +def tests_are_run_with_verbose_mode(testdir, test_execution): + test_execution['regular'] = testdir.runpytest('-v') + test_execution['gherkin'] = testdir.runpytest('--gherkin-terminal-reporter', '-v') + + +@when("tests are run with very verbose mode") +def tests_are_run_with_verbose_mode(testdir, test_execution): + test_execution['regular'] = testdir.runpytest('-vv') + test_execution['gherkin'] = testdir.runpytest('--gherkin-terminal-reporter', '-vv') + + +@then("output should contain single line feature description") +def output_should_contain_single_line_feature_description(test_execution): + ghe = test_execution['gherkin'] + assert ghe.ret == 0 + ghe.stdout.fnmatch_lines('Feature: Gherkin terminal output feature') + + +@then("output should contain single line scenario description") +def output_should_contain_single_line_scenario_description(test_execution): + ghe = test_execution['gherkin'] + assert ghe.ret == 0 + ghe.stdout.fnmatch_lines('*Scenario: Scenario example 1 PASSED') + + +@then("output must contain full gherkin scenario description") +def output_should_contain_single_line_scenario_description(test_execution): + ghe = test_execution['gherkin'] + assert ghe.ret == 0 + ghe.stdout.fnmatch_lines('*Scenario: Scenario example 1') + ghe.stdout.fnmatch_lines('*Given there is a bar') + ghe.stdout.fnmatch_lines('*When the bar is accessed') + ghe.stdout.fnmatch_lines('*Then world explodes') + ghe.stdout.fnmatch_lines('*PASSED') + + +@given('there is gherkin scenario without implementation') +def gherkin_scenario_without_implementation(testdir): + testdir.makefile('.feature', test=""" + Feature: Gherkin terminal output feature + Scenario: Scenario example 1 + Given there is a bar + When the bar is accessed + Then world explodes + """) + testdir.makepyfile(test_gherkin=""" + import pytest + from pytest_bdd import scenarios + + scenarios('.') + + """) + + +@when('tests are run with any verbosity mode') +def tests_are_run_with_any_verbosity_mode( + test_execution, verbosity_mode, testdir, + gherkin_scenario_without_implementation): + # test_execution['gherkin'] = testdir.runpytest( + # '--gherkin-terminal-reporter', '-vv') + if verbosity_mode[1]: + test_execution['gherkin'] = testdir.runpytest( + '--gherkin-terminal-reporter', verbosity_mode[1]) + else: + test_execution['gherkin'] = testdir.runpytest( + '--gherkin-terminal-reporter') + + +@then('output contains error about missing scenario implementation') +def output_contains_error_about_missing_scenario_implementation(test_execution): + ghe = test_execution['gherkin'] + assert ghe.ret + ghe.stdout.fnmatch_lines('''*StepDefinitionNotFoundError: Step definition is not found: Given "there is a bar". ''' + '''Line 3 in scenario "Scenario example 1"*''') + + +@given('there is gherkin scenario partially implemented') +def partially_implemented_gherkin_scenario(testdir): + testdir.makefile('.feature', test=""" + Feature: Gherkin terminal output feature + Scenario: Scenario example 1 + Given there is a bar + When the bar is accessed + Then world explodes + """) + testdir.makepyfile(test_gherkin=""" + import pytest + from pytest_bdd import given, when, scenario, then + + @given('there is a bar') + def a_bar(): + return 'bar' + + @when('the bar is accessed') + def the_bar_is_accessed(): + pass + + @scenario('test.feature', 'Scenario example 1') + def test_scenario_1(): + pass + """) + + +@then('output contains error about missing step implementation') +def output_contains_error_about_missing_step_implementation(test_execution): + ghe = test_execution['gherkin'] + assert ghe.ret + ghe.stdout.fnmatch_lines('''*StepDefinitionNotFoundError: Step definition is not found: Given "there is a bar". ''' + '''Line 3 in scenario "Scenario example 1"*''') + + +@given('there is gherkin scenario with broken implementation') +def there_is_gherkin_scenario_with_broken_implementation(testdir): + testdir.makefile('.feature', test=""" + Feature: Gherkin terminal output feature + Scenario: Scenario example 1 + Given there is a bar + When the bar is accessed + Then world explodes + """) + testdir.makepyfile(test_gherkin=""" + import pytest + from pytest_bdd import given, when, scenario, then + + @given('there is a bar') + def a_bar(request): + return 'bar' + + @when('the bar is accessed') + def the_bar_is_accessed(request): + local_var = 'value2' + raise Exception("ERROR") + + @scenario('test.feature', 'Scenario example 1') + def test_scenario_1(): + pass + """) + + +@when('tests are run with --showlocals') +def tests_are_run_with___showlocals(test_execution, testdir): + test_execution['gherkin'] = testdir.runpytest('--gherkin-terminal-reporter', '--showlocals') + + +@then('error traceback contains local variable descriptions') +def error_traceback_contains_local_variable_descriptions(test_execution): + ghe = test_execution['gherkin'] + assert ghe.ret + ghe.stdout.fnmatch_lines('''request*=* Date: Sun, 24 Jan 2016 00:44:29 +0100 Subject: [PATCH 2/5] Cleaned up hooks --- pytest_bdd/cucumber_json.py | 4 +- pytest_bdd/generation.py | 2 +- pytest_bdd/gherkin_terminal_reporter.py | 5 +- pytest_bdd/plugin.py | 49 ++++++++++++++++--- pytest_bdd/reporting.py | 19 ++----- .../feature/test_gherkin_terminal_reporter.py | 7 ++- 6 files changed, 54 insertions(+), 32 deletions(-) diff --git a/pytest_bdd/cucumber_json.py b/pytest_bdd/cucumber_json.py index dd8e94b6..f5977806 100644 --- a/pytest_bdd/cucumber_json.py +++ b/pytest_bdd/cucumber_json.py @@ -28,7 +28,7 @@ def add_options(parser): ) -def pytest_configure(config): +def configure(config): cucumber_json_path = config.option.cucumber_json_path # prevent opening json log on slave nodes (xdist) if cucumber_json_path and not hasattr(config, "slaveinput"): @@ -36,7 +36,7 @@ def pytest_configure(config): config.pluginmanager.register(config._bddcucumberjson) -def pytest_unconfigure(config): +def unconfigure(config): xml = getattr(config, "_bddcucumberjson", None) if xml is not None: del config._bddcucumberjson diff --git a/pytest_bdd/generation.py b/pytest_bdd/generation.py index 25ce47bc..31894122 100644 --- a/pytest_bdd/generation.py +++ b/pytest_bdd/generation.py @@ -39,7 +39,7 @@ def add_options(parser): ) -def pytest_cmdline_main(config): +def cmdline_main(config): """Check config option to show missing code.""" if config.option.generate_missing: return show_missing_code(config) diff --git a/pytest_bdd/gherkin_terminal_reporter.py b/pytest_bdd/gherkin_terminal_reporter.py index adf6b774..69fcc8bf 100644 --- a/pytest_bdd/gherkin_terminal_reporter.py +++ b/pytest_bdd/gherkin_terminal_reporter.py @@ -1,6 +1,4 @@ # -*- encoding: utf-8 -*- -import py -import pytest from _pytest.terminal import TerminalReporter @@ -18,8 +16,7 @@ def add_options(parser): ) -@pytest.mark.trylast -def pytest_configure(config): +def configure(config): if config.option.gherkin_terminal_reporter: # Get the standard terminal reporter plugin and replace it with our current_reporter = config.pluginmanager.getplugin('terminalreporter') diff --git a/pytest_bdd/plugin.py b/pytest_bdd/plugin.py index 08685790..2c1469c6 100644 --- a/pytest_bdd/plugin.py +++ b/pytest_bdd/plugin.py @@ -5,15 +5,9 @@ from . import given, when, then from . import cucumber_json from . import generation +from . import reporting from . import gherkin_terminal_reporter - -# Import hook handlers: -from .reporting import * -from .cucumber_json import * -from .generation import * -from .gherkin_terminal_reporter import * - from .fixtures import * @@ -41,3 +35,44 @@ def pytest_addoption(parser): cucumber_json.add_options(parser) generation.add_options(parser) gherkin_terminal_reporter.add_options(parser) + + +def pytest_configure(config): + """Configure all subplugins.""" + cucumber_json.configure(config) + gherkin_terminal_reporter.configure(config) + + +def pytest_unconfigure(config): + """Unconfigure all subplugins.""" + cucumber_json.unconfigure(config) + + +@pytest.mark.hookwrapper +def pytest_runtest_makereport(item, call): + outcome = yield + reporting.runtest_makereport(item, call, outcome.get_result()) + + +@pytest.mark.tryfirst +def pytest_bdd_before_scenario(request, feature, scenario): + reporting.before_scenario(request, feature, scenario) + + +@pytest.mark.tryfirst +def pytest_bdd_step_error(request, feature, scenario, step, step_func, step_func_args, exception): + reporting.step_error(request, feature, scenario, step, step_func, step_func_args, exception) + + +@pytest.mark.tryfirst +def pytest_bdd_before_step(request, feature, scenario, step, step_func): + reporting.before_step(request, feature, scenario, step, step_func) + + +@pytest.mark.tryfirst +def pytest_bdd_after_step(request, feature, scenario, step, step_func, step_func_args): + reporting.after_step(request, feature, scenario, step, step_func, step_func_args) + + +def pytest_cmdline_main(config): + generation.cmdline_main(config) diff --git a/pytest_bdd/reporting.py b/pytest_bdd/reporting.py index 8bb3ce2e..af94474c 100644 --- a/pytest_bdd/reporting.py +++ b/pytest_bdd/reporting.py @@ -6,8 +6,6 @@ import time -import pytest - class StepReport(object): @@ -145,11 +143,8 @@ def fail(self): self.add_step_report(report) -@pytest.mark.hookwrapper -def pytest_runtest_makereport(item, call): +def runtest_makereport(item, call, rep): """Store item in the report object.""" - outcome = yield - rep = outcome.get_result() try: scenario_report = item.__scenario_report__ except AttributeError: @@ -159,25 +154,21 @@ def pytest_runtest_makereport(item, call): rep.item = {"name": item.name} -@pytest.mark.tryfirst -def pytest_bdd_before_scenario(request, feature, scenario): +def before_scenario(request, feature, scenario): """Create scenario report for the item.""" request.node.__scenario_report__ = ScenarioReport(scenario=scenario, node=request.node) -@pytest.mark.tryfirst -def pytest_bdd_step_error(request, feature, scenario, step, step_func, step_func_args, exception): +def step_error(request, feature, scenario, step, step_func, step_func_args, exception): """Finalize the step report as failed.""" request.node.__scenario_report__.fail() -@pytest.mark.tryfirst -def pytest_bdd_before_step(request, feature, scenario, step, step_func): +def before_step(request, feature, scenario, step, step_func): """Store step start time.""" request.node.__scenario_report__.add_step_report(StepReport(step=step)) -@pytest.mark.tryfirst -def pytest_bdd_after_step(request, feature, scenario, step, step_func, step_func_args): +def after_step(request, feature, scenario, step, step_func, step_func_args): """Finalize the step report as successful.""" request.node.__scenario_report__.current_step_report.finalize(failed=False) diff --git a/tests/feature/test_gherkin_terminal_reporter.py b/tests/feature/test_gherkin_terminal_reporter.py index 8322be58..992ba84e 100644 --- a/tests/feature/test_gherkin_terminal_reporter.py +++ b/tests/feature/test_gherkin_terminal_reporter.py @@ -3,8 +3,7 @@ import pytest -from pytest_bdd import scenario, scenarios, given, when, then -from pytest_bdd import exceptions +from pytest_bdd import scenario, given, when, then @scenario('gherkin_terminal_reporter.feature', @@ -133,7 +132,7 @@ def tests_are_run_with_verbose_mode(testdir, test_execution): @when("tests are run with very verbose mode") -def tests_are_run_with_verbose_mode(testdir, test_execution): +def tests_are_run_with_very_verbose_mode(testdir, test_execution): test_execution['regular'] = testdir.runpytest('-vv') test_execution['gherkin'] = testdir.runpytest('--gherkin-terminal-reporter', '-vv') @@ -153,7 +152,7 @@ def output_should_contain_single_line_scenario_description(test_execution): @then("output must contain full gherkin scenario description") -def output_should_contain_single_line_scenario_description(test_execution): +def output_should_contain_full_gherkin_scenario_description(test_execution): ghe = test_execution['gherkin'] assert ghe.ret == 0 ghe.stdout.fnmatch_lines('*Scenario: Scenario example 1') From 94cba2a91c74f203342b2dd925b3170487333a95 Mon Sep 17 00:00:00 2001 From: Oleg Pidsadnyi Date: Sun, 24 Jan 2016 01:11:03 +0100 Subject: [PATCH 3/5] Trying to fix the tests --- pytest_bdd/plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest_bdd/plugin.py b/pytest_bdd/plugin.py index 2c1469c6..66ef10f5 100644 --- a/pytest_bdd/plugin.py +++ b/pytest_bdd/plugin.py @@ -37,6 +37,7 @@ def pytest_addoption(parser): gherkin_terminal_reporter.add_options(parser) +@pytest.mark.trylast def pytest_configure(config): """Configure all subplugins.""" cucumber_json.configure(config) From a7c38fe635697fd5dfd8da3354412c3bb6573a58 Mon Sep 17 00:00:00 2001 From: Oleg Pidsadnyi Date: Mon, 25 Jan 2016 17:02:05 +0100 Subject: [PATCH 4/5] Fixing the test --- pytest_bdd/gherkin_terminal_reporter.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pytest_bdd/gherkin_terminal_reporter.py b/pytest_bdd/gherkin_terminal_reporter.py index 69fcc8bf..2fadb499 100644 --- a/pytest_bdd/gherkin_terminal_reporter.py +++ b/pytest_bdd/gherkin_terminal_reporter.py @@ -34,6 +34,7 @@ def configure(config): class GherkinTerminalReporter(TerminalReporter): + def __init__(self, config): TerminalReporter.__init__(self, config) @@ -46,7 +47,7 @@ def pytest_runtest_logreport(self, report): rep = report res = self.config.hook.pytest_report_teststatus(report=rep) cat, letter, word = res - self.stats.setdefault(cat, []).append(rep) + if not letter and not word: # probably passed setup/teardown return @@ -94,3 +95,4 @@ def pytest_runtest_logreport(self, report): self._tw.write('\n\n') else: return TerminalReporter.pytest_runtest_logreport(self, rep) + self.stats.setdefault(cat, []).append(rep) From c68e787e81dd5f70799ef68aabfe6b4d4ac3016e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czy=C5=BC?= Date: Mon, 25 Jan 2016 23:45:34 +0000 Subject: [PATCH 5/5] update readme/changes about gherkin-terminal-reporter --- CHANGES.rst | 5 +++++ README.rst | 7 +++++++ pytest_bdd/__init__.py | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index de5d3e61..31213ea5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,11 @@ Changelog ========= +2.17.0 +------ + +- Add gherkin terminal reporter (spinus) + 2.16.0 ------ diff --git a/README.rst b/README.rst index 02b391d8..28f6e26c 100644 --- a/README.rst +++ b/README.rst @@ -1100,6 +1100,13 @@ To have an output in json format: py.test --cucumberjson= +To enable gherkin-formatted output on terminal, use + +:: + + py.test --gherkin-terminal-reporter + + Test code generation helpers ---------------------------- diff --git a/pytest_bdd/__init__.py b/pytest_bdd/__init__.py index 33636c49..cd76479f 100644 --- a/pytest_bdd/__init__.py +++ b/pytest_bdd/__init__.py @@ -3,6 +3,6 @@ from pytest_bdd.steps import given, when, then from pytest_bdd.scenario import scenario, scenarios -__version__ = '2.16.0' +__version__ = '2.17.0' __all__ = [given.__name__, when.__name__, then.__name__, scenario.__name__, scenarios.__name__]