diff --git a/pytest_bdd/parser.py b/pytest_bdd/parser.py index 0929208c1..1a43d3300 100644 --- a/pytest_bdd/parser.py +++ b/pytest_bdd/parser.py @@ -334,7 +334,10 @@ def params(self) -> tuple[str, ...]: def render(self, context: Mapping[str, Any]): def replacer(m: Match): varname = m.group(1) - return str(context[varname]) + try: + return str(context[varname]) + except KeyError: + return f"<{varname}>" return STEP_PARAM_RE.sub(replacer, self.name) diff --git a/tests/feature/test_steps.py b/tests/feature/test_steps.py index 1cb72b580..6decbe869 100644 --- a/tests/feature/test_steps.py +++ b/tests/feature/test_steps.py @@ -532,3 +532,36 @@ def check_stuff(stuff): "*Tearing down...*", ] ) + + +def test_missing_substitution_steps(testdir): + testdir.makefile( + ".feature", + steps=textwrap.dedent( + """\ + Feature: Missing substitutions are left as is + + Scenario: Missing substitution + Given Missing + """ + ), + ) + + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd import given, when, then, scenario + + @scenario("steps.feature", "Missing substitution") + def test_steps(): + pass + + @given('Missing ') + def foo(): + pass + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=1, failed=0)