Skip to content

Commit

Permalink
Merge branch 'ISSUE-139-gherkin-terminal-reporter' of git://github.co…
Browse files Browse the repository at this point in the history
…m/spinus/pytest-bdd into ISSUE-139-gherkin-terminal-reporter
  • Loading branch information
thedrow committed Sep 18, 2016
2 parents 2b4fc45 + c68e787 commit 2e2b7a5
Show file tree
Hide file tree
Showing 7 changed files with 434 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGES.rst
@@ -1,6 +1,11 @@
Changelog
=========

2.18.0
------

- Add gherkin terminal reporter (spinus + thedrow)

2.17.1
------

Expand Down
7 changes: 7 additions & 0 deletions README.rst
Expand Up @@ -1126,6 +1126,13 @@ To have an output in json format:
py.test --cucumberjson=<path to json report>


To enable gherkin-formatted output on terminal, use

::

py.test --gherkin-terminal-reporter


Test code generation helpers
----------------------------

Expand Down
2 changes: 1 addition & 1 deletion pytest_bdd/__init__.py
Expand Up @@ -3,6 +3,6 @@
from pytest_bdd.steps import given, when, then
from pytest_bdd.scenario import scenario, scenarios

__version__ = '2.17.1'
__version__ = '2.18.0'

__all__ = [given.__name__, when.__name__, then.__name__, scenario.__name__, scenarios.__name__]
98 changes: 98 additions & 0 deletions pytest_bdd/gherkin_terminal_reporter.py
@@ -0,0 +1,98 @@
# -*- encoding: utf-8 -*-

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"
)
)


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')
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

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)
self.stats.setdefault(cat, []).append(rep)
3 changes: 3 additions & 0 deletions pytest_bdd/plugin.py
Expand Up @@ -6,6 +6,7 @@
from . import cucumber_json
from . import generation
from . import reporting
from . import gherkin_terminal_reporter

from .fixtures import *

Expand Down Expand Up @@ -33,12 +34,14 @@ def pytest_addoption(parser):
"""Add pytest-bdd options."""
cucumber_json.add_options(parser)
generation.add_options(parser)
gherkin_terminal_reporter.add_options(parser)


@pytest.mark.trylast
def pytest_configure(config):
"""Configure all subplugins."""
cucumber_json.configure(config)
gherkin_terminal_reporter.configure(config)


def pytest_unconfigure(config):
Expand Down
42 changes: 42 additions & 0 deletions 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

0 comments on commit 2e2b7a5

Please sign in to comment.