Django DRF API endpoint can be called via Postman but gives back 404 not found in pytest

I'm currently rewriting our Django unit tests (written with django.unittest library) in pytest, and I'm encountering an issue.

I use a separate conftest.py file where I store my pytest fixtures and also load my JSON fixtures to fill the database with test data. One of my pytest fixture methods creates a user, and another one creates an authorized client. The user fixture also takes db as an argument. That's basically the base setup.

The test method calls an endpoint that includes the user_id in the URL. The call looks something like:

response = authorized_client.get(path=f"/user/{user_id}", headers=header)

Testing the endpoint manually in Postman gives back the user data and a 200 status code. However, pytest returns a 404 status code.

User.objects.exists(id=user_id)

This confirmed that the user exists in the database.

I investigated further and called the endpoint that retrieves all users. The user_id I used in the call to the endpoint was not included in the response. I suppose that's why I get a 404 back. The Question

Why do I get User.objects.exists(id=user_id) but the user with that ID is not actually there when I call the endpoint? Does pytest handle test database isolation differently than django.unittest so that the viewset can't access the test database? Could that be what is happening here?

I'm still new to pytest, so I wouldn't rule out the possibility that I'm doing something fundamentally wrong, but I couldn't find anything about this. Additional Information

I also tried calling the viewset directly with something similar to this:


@pytest.mark.django_db(transaction=True)
def test_viewset_direct_call(test_user):
    factory = APIRequestFactory()
    request = factory.get(f"/user/{test_user.id}")
    view = UserViewSet.as_view({"get": "retrieve"})
    response = view(request, pk=test_user.id)
    assert response.status_code == 200

This also results in 404 not found.

My pytest.fixture for creating the test user looks something like this:

@pytest.fixture
def test_user(db) -> User:
    with transaction.atomic():
        return User.objects.create_user(<test credentials go here>)
Вернуться на верх