pytest fixture – get value and avoid error "Fixture 'X' called directly"
Question:
I have updated pytest to 4.3.0 and now I need to rework test code since calling fixtures directly is deprecated.
I have an issue with fixtures used in an unittest.TestCase, how do I get the value returned from the fixture and not a reference to the function itself ?
Example :
@pytest.fixture
def test_value():
return 1
@pytest.mark.usefixtures("test_value")
class test_class(unittest.TestCase):
def test_simple_in_class(self):
print(test_value) # prints the function reference and not the value
print(test_value()) # fails with Fixtures are not meant to be called directly
def test_simple(test_value):
print(test_value) # prints 1
How can I get test_value in the test_simple_in_class() method ?
Answers:
There was a big discussion on this already. You can read through that or refer to the deprecation documentation.
In your contrived example it seems this is the answer:
@pytest.fixture(name="test_value")
def test_simple_in_class(self):
print(test_value())
However, I suggest checking the docs. The other example might be what you want. You can read the discussion I linked to for some of the reasoning. The debate got a bit heated though.
The solution to my simple example if anyone is interested.
def my_original_fixture():
return 1
@pytest.fixture(name="my_original_fixture")
def my_original_fixture_indirect():
return my_original_fixture()
@pytest.mark.usefixtures("my_original_fixture")
class test_class(unittest.TestCase):
def test_simple_in_class(self):
print(my_original_fixture())
def test_simple(my_original_fixture):
print(my_original_fixture)
I came to the following solution, it’s possible to import runtime_test_params somewhere where this is needed and use "parameterless" access. This requires no changes to the parameterless_function function API.
import pytest
runtime_test_params = {
"runtime_param": ""
}
@pytest.fixture(autouse=True ,params=["fixture param 1", "fixture param 2"], scope="session")
def sample_fixture(request):
runtime_test_params["runtime_param"] = request.param
yield request.param
def parameterless_function():
print(f"parameterless_function {runtime_test_params}")
def test_parameterless_function():
parameterless_function()
I have updated pytest to 4.3.0 and now I need to rework test code since calling fixtures directly is deprecated.
I have an issue with fixtures used in an unittest.TestCase, how do I get the value returned from the fixture and not a reference to the function itself ?
Example :
@pytest.fixture
def test_value():
return 1
@pytest.mark.usefixtures("test_value")
class test_class(unittest.TestCase):
def test_simple_in_class(self):
print(test_value) # prints the function reference and not the value
print(test_value()) # fails with Fixtures are not meant to be called directly
def test_simple(test_value):
print(test_value) # prints 1
How can I get test_value in the test_simple_in_class() method ?
There was a big discussion on this already. You can read through that or refer to the deprecation documentation.
In your contrived example it seems this is the answer:
@pytest.fixture(name="test_value")
def test_simple_in_class(self):
print(test_value())
However, I suggest checking the docs. The other example might be what you want. You can read the discussion I linked to for some of the reasoning. The debate got a bit heated though.
The solution to my simple example if anyone is interested.
def my_original_fixture():
return 1
@pytest.fixture(name="my_original_fixture")
def my_original_fixture_indirect():
return my_original_fixture()
@pytest.mark.usefixtures("my_original_fixture")
class test_class(unittest.TestCase):
def test_simple_in_class(self):
print(my_original_fixture())
def test_simple(my_original_fixture):
print(my_original_fixture)
I came to the following solution, it’s possible to import runtime_test_params somewhere where this is needed and use "parameterless" access. This requires no changes to the parameterless_function function API.
import pytest
runtime_test_params = {
"runtime_param": ""
}
@pytest.fixture(autouse=True ,params=["fixture param 1", "fixture param 2"], scope="session")
def sample_fixture(request):
runtime_test_params["runtime_param"] = request.param
yield request.param
def parameterless_function():
print(f"parameterless_function {runtime_test_params}")
def test_parameterless_function():
parameterless_function()