Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for scenario descriptions to be present #312

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
28 changes: 27 additions & 1 deletion pytest_bdd/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
STEP_PARAM_RE = re.compile(r"\<(.+?)\>")
COMMENT_RE = re.compile(r'(^|(?<=\s))#')

TYPES_WITH_DESCRIPTIONS = [types.FEATURE, types.SCENARIO, types.SCENARIO_OUTLINE]


def get_step_type(line):
"""Detect step type by the beginning of the line.
Expand Down Expand Up @@ -291,7 +293,8 @@ def __init__(self, basedir, filename, encoding="utf-8", strict_gherkin=True):
multiline_step = False
stripped_line = line.strip()
clean_line = strip_comments(line)
if not clean_line and (not prev_mode or prev_mode not in types.FEATURE):
if not clean_line and (not prev_mode or prev_mode not in TYPES_WITH_DESCRIPTIONS):
# Blank lines are included in feature and scenario descriptions
continue
mode = get_step_type(clean_line) or mode

Expand Down Expand Up @@ -340,6 +343,13 @@ def __init__(self, basedir, filename, encoding="utf-8", strict_gherkin=True):
# Remove Feature, Given, When, Then, And
keyword, parsed_line = parse_line(clean_line)
if mode in [types.SCENARIO, types.SCENARIO_OUTLINE]:
# Lines between the scenario declaration
# and the scenario's first step line
# are considered part of the scenario description.
if scenario and not keyword:
scenario.add_description_line(parsed_line)
continue

tags = get_tags(prev_line)
self.scenarios[parsed_line] = scenario = Scenario(self, parsed_line, line_number, tags=tags)
elif mode == types.BACKGROUND:
Expand Down Expand Up @@ -435,6 +445,7 @@ def __init__(self, feature, name, line_number, example_converters=None, tags=Non
self.tags = tags or set()
self.failed = False
self.test_function = None
self._description_lines = []

def add_step(self, step):
"""Add step to the scenario.
Expand All @@ -456,6 +467,21 @@ def steps(self):
result.extend(self._steps)
return result

def add_description_line(self, description_line):
"""Add a description line to the scenario.

:param str description_line:
"""
self._description_lines.append(description_line)

@property
def description(self):
"""Get the scenario's description.

:return: The scenario description
"""
return u"\n".join(self._description_lines).strip()

@property
def params(self):
"""Get parameter names.
Expand Down
4 changes: 4 additions & 0 deletions tests/feature/description.feature
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ Feature: Description

Scenario: Description

Also, the scenario can have a description.

It goes here between the scenario name
and the first step.
Given I have a bar
36 changes: 36 additions & 0 deletions tests/feature/scenario_descriptions.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Feature: Scenario Descriptions

Just as this feature has a feature descriptions,
which you are currently reading,
users should be able to add a description for a scenario

The scenarios in this feature file are skipped intentionally.
This issue: https://github.com/pytest-dev/pytest-bdd/issues/311
shows that scenario descriptions caused new tests to be created.
Those tests didn't have the markers attached to them,
so without the fix for that issue,
those new, rogue tests would fail with StepDefinitionNotFoundError.

If these scenarios' steps were implemented,
then all of these new, rogue tests would execute and pass.

@skip
Scenario: A scenario with a description
Here is a scenario description that is just one line

Given something
When I do something
Then something happens

@skip
Scenario: A scenario with a multiline description
Here is a scenario description.
It can also have more lines.

There can be line breaks too.
You just can't start a line with a real step keyword,
otherwise it will be treated as a step.

Given something
When I do something
Then something happens
4 changes: 4 additions & 0 deletions tests/feature/test_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,9 @@ def test():


Some description goes here."""
assert test.__scenario__.description == """Also, the scenario can have a description.

It goes here between the scenario name
and the first step."""

test(request)
4 changes: 4 additions & 0 deletions tests/feature/test_scenario_descriptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from pytest_bdd import scenarios

# See feature file for reasons for executing (skipping) these tests
scenarios("scenario_descriptions.feature")
rbcasperson marked this conversation as resolved.
Show resolved Hide resolved