better reporting

This commit is contained in:
Anatoly Bubenkov 2014-07-25 22:17:58 +02:00
parent 9f24385897
commit 5aaf42e4b5
5 changed files with 45 additions and 22 deletions

View File

@ -67,7 +67,7 @@ class LogBDDCucumberJSON(object):
def stepmap(step):
return {
"keyword": step['type'].capitalize(),
"keyword": step['keyword'],
"name": step['name'],
"line": step['line_number'],
"match": {
@ -80,7 +80,7 @@ class LogBDDCucumberJSON(object):
self.features[scenario['feature']['filename']] = {
"keyword": "Feature",
"uri": scenario['feature']['rel_filename'],
"name": scenario['feature']['name'],
"name": scenario['feature']['name'] or scenario['feature']['rel_filename'],
"id": scenario['feature']['rel_filename'].lower().replace(' ', '-'),
"line": scenario['feature']['line_number'],
"description": scenario['feature']['description'],

View File

@ -96,18 +96,17 @@ def strip_comments(line):
return line.strip()
def remove_prefix(line):
"""Remove the step prefix (Scenario, Given, When, Then or And).
def parse_line(line):
"""Parse step line to get the step prefix (Scenario, Given, When, Then or And) and the actual step name.
:param line: Line of the Feature file.
:return: Line without the prefix.
:return: `tuple` in form ('<prefix>', '<Line without the prefix>').
"""
for prefix, _ in STEP_PREFIXES:
if line.startswith(prefix):
return line[len(prefix):].strip()
return line
return prefix.strip(), line[len(prefix):].strip()
return '', line
def _open_file(filename, encoding):
@ -187,7 +186,7 @@ class Feature(object):
if mode == types.FEATURE:
if prev_mode != types.FEATURE:
self.name = remove_prefix(clean_line)
_, self.name = parse_line(clean_line)
self.line_number = line_number
else:
description.append(clean_line)
@ -195,7 +194,7 @@ class Feature(object):
prev_mode = mode
# Remove Feature, Given, When, Then, And
clean_line = remove_prefix(clean_line)
keyword, clean_line = parse_line(clean_line)
if mode in [types.SCENARIO, types.SCENARIO_OUTLINE]:
self.scenarios[clean_line] = scenario = Scenario(self, clean_line, line_number)
elif mode == types.EXAMPLES:
@ -212,7 +211,8 @@ class Feature(object):
scenario.add_example_row(clean_line[0], clean_line[1:])
elif mode and mode != types.FEATURE:
step = scenario.add_step(
step_name=clean_line, step_type=mode, indent=line_indent, line_number=line_number)
step_name=clean_line, step_type=mode, indent=line_indent, line_number=line_number,
keyword=keyword)
self.description = u'\n'.join(description)
@ -253,17 +253,20 @@ class Scenario(object):
self.line_number = line_number
self.example_converters = example_converters
def add_step(self, step_name, step_type, indent, line_number):
def add_step(self, step_name, step_type, indent, line_number, keyword):
"""Add step to the scenario.
:param step_name: Step name.
:param step_type: Step type.
:param indent: `int` step text indent
:param line_number: `int` line number
:param keyword: `str` step keyword
"""
params = get_step_params(step_name)
self.params.update(params)
step = Step(
name=step_name, type=step_type, params=params, scenario=self, indent=indent, line_number=line_number)
name=step_name, type=step_type, params=params, scenario=self, indent=indent, line_number=line_number,
keyword=keyword)
self.steps.append(step)
return step
@ -340,8 +343,9 @@ class Step(object):
"""Step."""
def __init__(self, name, type, params, scenario, indent, line_number):
def __init__(self, name, type, params, scenario, indent, line_number, keyword):
self.name = name
self.keyword = keyword
self.lines = []
self.indent = indent
self.type = type

View File

@ -28,8 +28,9 @@ def pytest_runtest_makereport(item, call, __multicall__):
else:
rep.scenario = {
'steps': [{
'name': step._name,
'name': step.name,
'type': step.type,
'keyword': step.keyword,
'line_number': step.line_number
} for step in scenario.steps],
'name': scenario.name,

View File

@ -39,13 +39,14 @@ import sys # pragma: no cover
import pytest # pragma: no cover
from pytest_bdd.feature import remove_prefix # pragma: no cover
from pytest_bdd.feature import parse_line # pragma: no cover
from pytest_bdd.types import GIVEN, WHEN, THEN # pragma: no cover
PY3 = sys.version_info[0] >= 3 # pragma: no cover
class StepError(Exception): # pragma: no cover
"""Step declaration error."""
RE_TYPE = type(re.compile('')) # pragma: no cover
@ -63,7 +64,6 @@ def given(name, fixture=None, converters=None):
:note: Can't be used as a decorator when the fixture is specified.
"""
if fixture is not None:
module = get_caller_module()
step_func = lambda request: request.getfuncargvalue(fixture)
@ -73,7 +73,8 @@ def given(name, fixture=None, converters=None):
step_func.fixture = fixture
func = pytest.fixture(lambda: step_func)
func.__doc__ = 'Alias for the "{0}" fixture.'.format(fixture)
contribute_to_module(module, remove_prefix(name), func)
_, name = parse_line(name)
contribute_to_module(module, name, func)
return _not_a_fixture_decorator
return _step_decorator(GIVEN, name, converters=converters)

View File

@ -35,6 +35,7 @@ def test_step_trace(testdir, equals_any):
Scenario: Passing
Given a passing step
And some other passing step
Scenario: Failing
Given a failing step
@ -47,6 +48,10 @@ def test_step_trace(testdir, equals_any):
def a_passing_step():
return 'pass'
@given('some other passing step')
def some_other_passing_step():
return 'pass'
@given('a failing step')
def a_failing_step():
raise Exception('Error')
@ -82,7 +87,19 @@ def test_step_trace(testdir, equals_any):
"result": {
"status": "passed"
}
},
{
"keyword": "And",
"line": 5,
"match": {
"location": ""
},
"name": "some other passing step",
"result": {
"status": "passed"
}
}
],
"tags": [],
"type": "scenario"
@ -91,12 +108,12 @@ def test_step_trace(testdir, equals_any):
"description": "",
"id": "test_failing",
"keyword": "Scenario",
"line": 6,
"line": 7,
"name": "Failing",
"steps": [
{
"keyword": "Given",
"line": 7,
"line": 8,
"match": {
"location": ""
},
@ -111,7 +128,7 @@ def test_step_trace(testdir, equals_any):
"type": "scenario"
}
],
"id": "one-passing-scenario,-one-failing-scenario",
"id": "test_step_trace0/test.feature",
"keyword": "Feature",
"line": 1,
"name": "One passing scenario, one failing scenario",