There is different behaviour when a fixture returning a yield is called with usefixtures (returns func) and without using usefixtures (i.e. as using arg in test function).
Below is the code with two test functions. One uses fixture_value fixture (which yields a string value) as an arg, and the other uses it using usefixtures method.
The expectation is, in both cases we should get the string value yielded by fixture, and they should PASS, but instead, it returns a function obj when used using usefixtures and _one of the test case FAILS_.
import pytest
@pytest.fixture(scope="function")
def fixture_value():
print("\n== fixture_value called!")
yield "expected_value"
print("\n== fixture_value returned!")
def test_cond1(fixture_value):
print(f"Testing fixture without usefixtures, value is: {fixture_value}")
assert fixture_value == "expected_value"
@pytest.mark.usefixtures("fixture_value")
def test_cond2():
print(f"Testing fixture with usefixtures, value is: {fixture_value}")
assert fixture_value == "expected_value"
Output:
pytest -vs test_pytest_demo\test_pytest_yield_with_usefixture.py
===================================================================================== test session starts =====================================================================================
platform win32 -- Python 3.8.1, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- e:\work\sample_demo\.tenv\scripts\python.exe
cachedir: .pytest_cache
rootdir: E:\work\sample_demo
collected 2 items
test_pytest_demo/test_pytest_yield_with_usefixture.py::test_cond1
== fixture_value called!
Testing fixture without usefixtures, value is: expected_value
PASSED
== fixture_value returned!
test_pytest_demo/test_pytest_yield_with_usefixture.py::test_cond2
== fixture_value called!
Testing fixture with usefixtures, value is: <function fixture_value at 0x032DDC88>
FAILED
== fixture_value returned!
pip list output in my venv:
Package Version
-------------- -------
atomicwrites 1.4.0
attrs 19.3.0
colorama 0.4.3
more-itertools 8.3.0
packaging 20.4
pip 19.2.3
pluggy 0.13.1
py 1.8.1
pyparsing 2.4.7
pytest 5.4.2
setuptools 41.2.0
six 1.15.0
wcwidth 0.1.9
pip list from the virtual environment you are usingthis is about python names/aliases and what happens if a function name is the same as a parameter name, but the parameter name was stripped
as the fixture is in the same file, if its not requested by the function name, the code will actually just get the global with the same name
if you used something like
@pytest.fixture(name="fixture_value")
def _hidden_fixture_value():
...
you would observe a NameError instead of the type/reference aliasing issue you see
Thanks for explaining and clearing my doubt. Closing it now!