pytest-dev / pytest-dev/pytest-asyncio
[pytest-django] Database is not properly rolled back after async tests
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.7k
- Forks
- 207
- Avg merge
- 5h 35m
- Merged PRs (30d)
- 9
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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the failure from the issue's test_app.py example with pytest, pytest-django, and pytest-asyncio. Verify whether the async test's database write remains visible to test_check_if_model_present; done means the second test passes with the write rolled back after the first test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- databases, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100