Testing in Python: Pytest fixtures scope

Mangabo Kolawole - Jul 4 '22 - - Dev Community

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)
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Also, learning about pytest scopes can be helpful to better the organization of fixtures in your tests.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player