I am relatively new to pytest, so I understand the simple use of fixtures that looks like that:
@pytest.fixture
def example_data():
return "abc"
and then using it in a way like this:
def test_data(self, example_data):
assert example_data == "abc"
I am working on a django app and where it gets confusing is when I try to use fixtures to create django objects that will be used for the tests. The closest solution that I've found online looks like that:
@pytest.fixture
def test_data(self):
users = get_user_model()
client = users.objects.get_or_create(username="test_user", password="password")
and then I am expecting to be able to access this user object in a test function:
@pytest.mark.django_db
@pytest.mark.usefixtures("test_data")
async def test_get_users(self):
# the user object should be included in this queryset
all_users = await sync_to_async(User.objects.all)()
.... (doing assertions) ...
The issue is that when I try to list all the users I can't find the one that was created as part of the test_data
fixture and therefore can't use it for testing.
I noticed that if I create the objects inside the function then there is no problem, but this approach won't work for me because I need to parametrize the function and depending on the input add different groups to each user.
I also tried some type of init
or setup
function for my testing class and creating the User test objects from there but this doesn't seem to be pytest's recommended way of doing things. But either way that approach didn't work either when it comes to listing them later.
Is there any way to create test objects which will be accessible when doing a queryset? Is the right way to manually create separate functions and objects for each test case or is there a pytest-way of achieving that?
When using pytest-django
there are some in-built fixtures that you can use already that help you with setting things up. When using such a fixture you do not need the decorators anymore.
Your code will then look like this:
@pytest.fixture
def client(django_user_model):
client = django_user_model.objects.get_or_create(username="test_user", password="password")
return client
def test_get_users(client, django_user_model):
# the user object should be included in this queryset
all_users = django_user_model.objects.all()
assert all_users.count() == 1
Also there is no need for self
in the fixture or test.