Description
When using pytest-django's pytest.mark.django_db
marker in conjunction with pytest.mark.asyncio
, any writes to the database are not rolled back when the test completes and affect subsequent tests.
To test, I created a fresh django app, installed pytest-django
and pytest-asyncio
, created a simple model, and wrote two tests:
models.py:
from django.db import models
class MyModel(models.Model):
my_field = models.TextField(null=True, blank=True)
test_app.py:
import pytest
from asgiref.sync import sync_to_async
from app.models import MyModel
@pytest.mark.django_db
@pytest.mark.asyncio
async def test_save_model_to_db():
await sync_to_async(MyModel.objects.create)()
@pytest.mark.django_db
def test_check_if_model_present():
assert MyModel.objects.count() == 0
Running pytest
resulted in the first test succeeding and the second failing:
@pytest.mark.django_db
def test_check_if_model_present():
> assert MyModel.objects.count() == 0
E assert 1 == 0
At first I thought it might be due to how Django runs synchronous code from an asynchronous context. Maybe it was creating the instance in another transaction that pytest wasn't rolling back.
So, I updated the test code to set DJANGO_ALLOW_ASYNC_UNSAFE to "true" so I could remove the sync_to_async()
wrapper around the create()
call, ensuring the instance would be included created in the same thread and within pytest's transaction.
Unfortunately, the test failed for the same reason. This could be an issue with pytest-asyncio or compatibility with pytest-django.