I know fixtures can use other fixtures, but can a hook use a fixture? I searched a lot on net but could not get any help. Can someone please point if I am doing any mistake here?
#conftest.py
@pytest.fixture()
def json_loader(request):
"""Loads the data from given JSON file"""
def _loader(filename):
import json
with open(filename, 'r') as f:
data = json.load(f)
return data
return _loader
def pytest_runtest_setup(item,json_loader): #hook fails to use json_loader
data = json_loader("some_file.json")
print(data)
#do something useful here with data
I get the following error when I run it.
pluggy.manager.PluginValidationError: Plugin 'C:\some_path\conftest.py' for hook 'pytest_runtest_setup' hookimpl definition: pytest_runtest_setup(item, json_loader) Argument(s) {'json_loader'} are declared in the hookimpl but can not be found in the hookspec
Even if I do not pass json_loader as an arg to pytest_runtest_setup(), I get an error saying "Fixture "json_loader" called directly. Fixtures are not meant to be called directly"
It seems the only current supported way to dynamically instantiate fixtures is via the request
fixture, specifically the getfixturevalue
method
This isn't accessible before test time in a pytest hook, but you can accomplish the same by using a fixture yourself
Here's a (contrived) example:
import pytest
@pytest.fixture
def load_data():
def f(fn):
# This is a contrived example, in reality you'd load data
return f'data from {fn}'
return f
TEST_DATA = None
@pytest.fixture(autouse=True)
def set_global_loaded_test_data(request):
global TEST_DATA
data_loader = request.getfixturevalue('load_data')
orig, TEST_DATA = TEST_DATA, data_loader(f'{request.node.name}.txt')
yield
TEST_DATA = orig
def test_foo():
assert TEST_DATA == 'data from test_foo.txt'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With