Skip to content

Commit ea46856

Browse files
authored
Patch pytest-bdd fixture injection (#2112)
Issue: pytest-dev/pytest-bdd#689 Fix: pytest-dev/pytest-bdd#690 Since that issue has been open for months, we incorporate a patch here to be removed when the fix is merged upstream.
1 parent 409df02 commit ea46856

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

requirements/test.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ coveralls
55
lxml
66
pytest
77
pytest-asyncio
8-
pytest-bdd
8+
pytest-bdd # See tests/conftest.py for a patch for version 7.2.0
99
pytest-cov
1010
pytest-dotenv
1111
pytest-env

requirements/test.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ parse-type==0.6.2
3333
# via pytest-bdd
3434
pluggy==1.5.0
3535
# via pytest
36-
pytest==8.0.0
36+
pytest==8.3.2
3737
# via
3838
# -r requirements/test.in
3939
# pytest-asyncio
@@ -50,7 +50,7 @@ pytest-asyncio==0.23.8
5050
# via -r requirements/test.in
5151
pytest-base-url==2.1.0
5252
# via pytest-playwright
53-
pytest-bdd==7.0.1
53+
pytest-bdd==7.2.0
5454
# via -r requirements/test.in
5555
pytest-cov==5.0.0
5656
# via -r requirements/test.in

tests/conftest.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,68 @@ def pytest_runtest_call(item: pytest.Function) -> None:
130130
typeguard.check_type(item.funcargs[attr], type_)
131131

132132

133+
# MARK: Pytest-bdd patch ---------------------------------------------------------------
134+
135+
136+
@pytest.fixture(scope='session', autouse=True)
137+
def _patch_pytest_bdd_inject_fixture() -> None:
138+
"""Patch pytest-bdd 7.2.0 for pytest 8.1."""
139+
# Reported issue: https://github.com/pytest-dev/pytest-bdd/issues/689
140+
# Pending fix: https://github.com/pytest-dev/pytest-bdd/pull/690
141+
# Remove this function when that PR is accepted and incorporated in a release
142+
143+
# pylint: disable=protected-access
144+
from _pytest.fixtures import FixtureDef, FixtureRequest
145+
146+
def inject_fixture(request: FixtureRequest, arg: str, value: Any) -> None:
147+
"""
148+
Inject fixture into pytest fixture request.
149+
150+
:param request: pytest fixture request
151+
:param arg: argument name
152+
:param value: argument value
153+
"""
154+
fd = FixtureDef(
155+
config=request._fixturemanager.config,
156+
baseid=request.node.nodeid,
157+
argname=arg,
158+
func=lambda: value,
159+
scope="function",
160+
params=None,
161+
ids=None,
162+
_ispytest=True,
163+
)
164+
165+
fd.cached_result = (value, 0, None)
166+
167+
old_fd = request._fixture_defs.get(arg)
168+
add_fixturename = arg not in request.fixturenames
169+
170+
def fin() -> None:
171+
request._fixturemanager._arg2fixturedefs[arg].remove(fd)
172+
173+
if old_fd is not None:
174+
request._fixture_defs[arg] = old_fd
175+
176+
if add_fixturename:
177+
request._pyfuncitem._fixtureinfo.names_closure.remove(arg)
178+
179+
request.addfinalizer(fin)
180+
181+
# inject fixture definition
182+
request._fixturemanager._arg2fixturedefs.setdefault(arg, []).append(fd)
183+
184+
# inject fixture value in request cache
185+
request._fixture_defs[arg] = fd
186+
if add_fixturename:
187+
request._pyfuncitem._fixtureinfo.names_closure.append(arg)
188+
189+
# Apply patch to the (sole) function using it
190+
from pytest_bdd.scenario import _execute_step_function
191+
192+
_execute_step_function.__globals__['inject_fixture'] = inject_fixture
193+
194+
133195
# MARK: Playwright browser config ------------------------------------------------------
134196

135197

0 commit comments

Comments
 (0)