So I have this problem with pytest with fixtures of fixtures.
Assume we have a following code. sample_search_page_url
is a fixture which depends on fixture sample_query
. They are defined in a single file.
fixtures.py
import pytest
import pathlib
from ..historiography.scrape.leninka import (
urlencode
)
@pytest.fixture
def sample_query() -> str:
return 'Amazing kitty cats'
@pytest.fixture
def sample_search_page_url(sample_query) -> str:
return f"https://cyberleninka.ru/search?q={urlencode(sample_query)}&page=1"
test.py
from fixtures import sample_search_page_url
def test_something_with_fixture_of_fixture(sample_search_page_url):
assert isinstance(sample_search_page_url)
If you used pytest before, you know that such code will result in fixture sample_query
not being found error, when it is required by sample_search_page_url
fixture.
That seems unintuitive, because as you might think one must be in the scope of other due to being declared in one scope. However, it somehow, isn't that way.
I want to write complex fixtures (e.g. setting up an environment) which consist of other fixtures which I use in other test files.
The question is, how to do it gracefully, without having to specify all fixtures which are dependencies of a fixture in test files?
One of the clean solutions which came to my mind was to use from fixtures import *
. However, as far as I know it is a bad practice (e.g. why is import bad)
The other solution is to import dependables one by one, but I see it unreasonable to import dependencies for a fixture, when I don't use them explicitly in my code. It goes the encapsulation I'm trying to achieve.
What would be a graceful way to deal with this fixture imports problem?
You can use conftest.py to place your fixtures and then you don't need to import any fixtures by using
from fixtures import ...
which is wrong usage of fixtures. You should not import them but request. This way you won't face with sample_query not being found error.
You all need to do is request fixture(s) you want as an argument in your any test functions.
Example:
conftest.py
import pytest
import pathlib
from ..historiography.scrape.leninka import (
urlencode
)
@pytest.fixture
def sample_query() -> str:
return 'Amazing kitty cats'
@pytest.fixture
def sample_search_page_url(sample_query) -> str:
return f"https://cyberleninka.ru/search?q={urlencode(sample_query)}&page=1"
test.py
def test_something_with_fixture_of_fixture(sample_search_page_url):
assert isinstance(sample_search_page_url)
test2.py
def test_something_with_fixture(sample_query):
assert sample_query == "Amazing kitty cats"