I was recently working on a Django project. We decided to use pytest
to write the tests because we planned to have a lot of unit tests, and pytest is very and ridiculously fast.
The project uses a lot of fixtures, and we quickly ran into a problem: something I will call fixtures hell. Let me explain.
The problem
We have a fixture that uses another fixture.
import pytest
pytest.fixture
def user():
return User.objects.create(name="foo")
pytest.fixture
def business(user):
return Business.objects.create(name="foo", owner=user)
Now, if we want to use the business feature in a test, it won't work and return an error.
import pytest
pytest.mark.django_db
def test_activate_business(business):
business.activate()
This is because the business
fixture depends on the user
fixture, thus, we need to add the business
fixture and the user
fixture. And the business
fixture was also shared between multiple tests.
Solution
We decided to add the fixture in the conftest.py
file. Doing this, the fixture was available on multiple tests and set the autouse
to True
so you don't even need to require it in your tests.
import pytest
pytest.fixture
def user():
return User.objects.create(name="foo")
pytest.fixture(autouse=True)
def business(user):
return Business.objects.create(name="foo", owner=user)
Also, learning about pytest scopes
can be helpful to better the organization of fixtures in your tests.