Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Fixed
* Backslashes in datatable and examples table cells are no longer over-quoted. A cell containing a single backslash now reaches the step as a single backslash, matching the Gherkin escaping rules. If you compensated by doubling backslashes in feature files, undo that. `#769 <https://github.com/pytest-dev/pytest-bdd/issues/769>`_
* 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>`_
* 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>`_
* Injecting a ``target_fixture`` no longer emits ``PytestRemovedIn10Warning`` on pytest 9.1+, which deprecated passing ``nodeid`` to ``_register_fixture``. `#823 <https://github.com/pytest-dev/pytest-bdd/issues/823>`_

Security
++++++++
Expand Down
10 changes: 8 additions & 2 deletions src/pytest_bdd/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,17 @@ def inject_fixture(request: FixtureRequest, arg: str, value: object) -> None:
:param arg: argument name
:param value: argument value
"""
# Ensure there's a fixture definition for the argument
# Ensure there's a fixture definition for the argument.
# pytest 9.1 deprecated the ``nodeid`` argument in favour of ``node``.
scoping: dict[str, object]
if pytest_version.release >= (9, 1):
scoping = {"node": request.node}
else:
scoping = {"nodeid": request.node.nodeid}
request._fixturemanager._register_fixture(
name=arg,
func=lambda: value,
nodeid=request.node.nodeid,
**scoping, # type: ignore[arg-type]
)
# Note the fixture we just registered will have a lower priority
# if there was already one registered, so we need to force its value
Expand Down
39 changes: 39 additions & 0 deletions tests/steps/test_given.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,42 @@ def _(foo):
)
result = pytester.runpytest()
result.assert_outcomes(passed=1)


def test_given_injection_no_deprecation_warning(pytester):
"""Injecting a target fixture must not emit pytest deprecation warnings."""
pytester.makefile(
".feature",
given=textwrap.dedent(
"""\
Feature: Given
Scenario: Test given fixture injection
Given I have injecting given
Then foo should be "injected foo"
"""
),
)
pytester.makepyfile(
textwrap.dedent(
"""\
from pytest_bdd import given, then, scenario

@scenario("given.feature", "Test given fixture injection")
def test_given():
pass


@given("I have injecting given", target_fixture="foo")
def _():
return "injected foo"


@then('foo should be "injected foo"')
def _(foo):
assert foo == "injected foo"

"""
)
)
result = pytester.runpytest("-W", "error::DeprecationWarning", "-W", "error::PendingDeprecationWarning")
result.assert_outcomes(passed=1)
38 changes: 38 additions & 0 deletions tests/test_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Compat tests."""

from __future__ import annotations

from unittest import mock

from packaging.version import parse as parse_version

import pytest_bdd.compat as compat


def test_inject_fixture_uses_node_on_pytest_9_1_and_later(monkeypatch):
"""inject_fixture passes ``node=`` once pytest deprecates ``nodeid=``."""
monkeypatch.setattr(compat, "pytest_version", parse_version("9.1.0"))
request = mock.Mock()

compat.inject_fixture(request, "my_fixture", "my_value")

_, kwargs = request._fixturemanager._register_fixture.call_args
assert kwargs["name"] == "my_fixture"
assert kwargs["node"] is request.node
assert "nodeid" not in kwargs
assert kwargs["func"]() == "my_value"


def test_inject_fixture_uses_nodeid_before_pytest_9_1(monkeypatch):
"""inject_fixture keeps passing ``nodeid=`` on pytest < 9.1."""
monkeypatch.setattr(compat, "pytest_version", parse_version("9.0.0"))
request = mock.Mock()
request.node.nodeid = "test_foo.py::test_bar"

compat.inject_fixture(request, "my_fixture", "my_value")

_, kwargs = request._fixturemanager._register_fixture.call_args
assert kwargs["name"] == "my_fixture"
assert kwargs["nodeid"] == "test_foo.py::test_bar"
assert "node" not in kwargs
assert kwargs["func"]() == "my_value"