Skip to content

Commit 487e952

Browse files
committed
Add scenario descriptions
1 parent b392a9e commit 487e952

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

src/pytest_bdd/parser.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
("But ", None),
2929
]
3030

31+
TYPES_WITH_DESCRIPTIONS = [types.FEATURE, types.SCENARIO, types.SCENARIO_OUTLINE]
32+
3133
if typing.TYPE_CHECKING:
3234
from typing import Any, Iterable, Mapping, Match, Sequence
3335

@@ -125,7 +127,8 @@ def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> Featu
125127
multiline_step = False
126128
stripped_line = line.strip()
127129
clean_line = strip_comments(line)
128-
if not clean_line and (not prev_mode or prev_mode not in types.FEATURE):
130+
if not clean_line and (not prev_mode or prev_mode not in TYPES_WITH_DESCRIPTIONS):
131+
# Blank lines are included in feature and scenario descriptions
129132
continue
130133
mode = get_step_type(clean_line) or mode
131134

@@ -142,7 +145,9 @@ def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> Featu
142145
feature.line_number = line_number
143146
feature.tags = get_tags(prev_line)
144147
elif prev_mode == types.FEATURE:
145-
description.append(clean_line)
148+
# Do not include comments in descriptions
149+
if not stripped_line.startswith("#"):
150+
description.append(line)
146151
else:
147152
raise exceptions.FeatureError(
148153
"Multiple features are not allowed in a single feature file",
@@ -157,6 +162,15 @@ def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> Featu
157162
keyword, parsed_line = parse_line(clean_line)
158163

159164
if mode in [types.SCENARIO, types.SCENARIO_OUTLINE]:
165+
# Lines between the scenario declaration
166+
# and the scenario's first step line
167+
# are considered part of the scenario description.
168+
if scenario and not keyword:
169+
# Do not include comments in descriptions
170+
if stripped_line.startswith("#"):
171+
continue
172+
scenario.add_description_line(line)
173+
continue
160174
tags = get_tags(prev_line)
161175
scenario = ScenarioTemplate(
162176
feature=feature,
@@ -215,6 +229,7 @@ class ScenarioTemplate:
215229
tags: set[str] = field(default_factory=set)
216230
examples: Examples | None = field(default_factory=lambda: Examples())
217231
_steps: list[Step] = field(init=False, default_factory=list)
232+
_description_lines: list[str] = field(init=False, default_factory=list)
218233

219234
def add_step(self, step: Step) -> None:
220235
step.scenario = self
@@ -241,7 +256,20 @@ def render(self, context: Mapping[str, Any]) -> Scenario:
241256
for step in self._steps
242257
]
243258
steps = background_steps + scenario_steps
244-
return Scenario(feature=self.feature, name=self.name, line_number=self.line_number, steps=steps, tags=self.tags)
259+
return Scenario(feature=self.feature, name=self.name, line_number=self.line_number, steps=steps, tags=self.tags, description=self._description_lines)
260+
261+
def add_description_line(self, description_line):
262+
"""Add a description line to the scenario.
263+
:param str description_line:
264+
"""
265+
self._description_lines.append(description_line)
266+
267+
@property
268+
def description(self):
269+
"""Get the scenario's description.
270+
:return: The scenario description
271+
"""
272+
return u"\n".join(self._description_lines)
245273

246274

247275
@dataclass
@@ -251,6 +279,7 @@ class Scenario:
251279
line_number: int
252280
steps: list[Step]
253281
tags: set[str] = field(default_factory=set)
282+
description: list[str] = field(default_factory=list)
254283

255284

256285
@dataclass

0 commit comments

Comments
 (0)