Skip to content

Commit 28ac968

Browse files
committed
Fix empty docstring delivery to step functions (#809)
ScenarioTemplate.steps_from_template_steps used a truthy check (`if step.docstring`) when building the step list. An empty docstring is a valid value, but `""` is falsy, so the docstring was replaced with None. The step then looked like it had no docstring at all, and pytest fell back to fixture lookup, raising "fixture 'docstring' not found". Switched the check to `is not None` so empty docstrings are passed through as `""`. Added a regression test in tests/steps/test_docstring.py.
1 parent 234fdeb commit 28ac968

3 files changed

Lines changed: 52 additions & 1 deletion

File tree

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Removed
3030
Fixed
3131
+++++
3232
* Made type annotations stronger and removed most of the ``typing.Any`` usages and ``# type: ignore`` annotations. `#658 <https://github.com/pytest-dev/pytest-bdd/pull/658>`_
33+
* Empty docstrings are now correctly forwarded to step functions as an empty string instead of being silently dropped, which previously caused pytest to report a missing ``docstring`` fixture. `#809 <https://github.com/pytest-dev/pytest-bdd/issues/809>`_
3334

3435
Security
3536
++++++++

src/pytest_bdd/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def render(self, context: Mapping[str, object]) -> Scenario:
217217
line_number=step.line_number,
218218
keyword=step.keyword,
219219
datatable=step.render_datatable(step.datatable, context) if step.datatable else None,
220-
docstring=render_string(step.docstring, context) if step.docstring else None,
220+
docstring=render_string(step.docstring, context) if step.docstring is not None else None,
221221
)
222222
for step in base_steps
223223
]

tests/steps/test_docstring.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,56 @@ def _():
197197
result.assert_outcomes(passed=1)
198198

199199

200+
def test_steps_with_empty_docstring(pytester):
201+
"""Regression test for #809.
202+
203+
An empty docstring must be passed to the step function as an empty
204+
string. Before the fix it was dropped, and pytest then treated
205+
``docstring`` as a missing fixture.
206+
"""
207+
pytester.makefile(
208+
".feature",
209+
empty_docstring=textwrap.dedent(
210+
'''\
211+
Feature: Empty docstring
212+
213+
Scenario: Step receives an empty docstring
214+
Given a step has an empty docstring
215+
"""
216+
"""
217+
'''
218+
),
219+
)
220+
pytester.makeconftest(
221+
textwrap.dedent(
222+
r"""
223+
from pytest_bdd import given
224+
from pytest_bdd.utils import dump_obj
225+
226+
227+
@given("a step has an empty docstring")
228+
def _(docstring):
229+
dump_obj(docstring)
230+
"""
231+
)
232+
)
233+
pytester.makepyfile(
234+
textwrap.dedent(
235+
"""\
236+
from pytest_bdd import scenarios
237+
238+
scenarios("empty_docstring.feature")
239+
"""
240+
)
241+
)
242+
243+
result = pytester.runpytest("-s")
244+
result.assert_outcomes(passed=1)
245+
246+
docstrings = collect_dumped_objects(result)
247+
assert docstrings == [""]
248+
249+
200250
def test_docstring_step_argument_is_reserved_and_cannot_be_used(pytester):
201251
pytester.makefile(
202252
".feature",

0 commit comments

Comments
 (0)