#35660 closed Bug (fixed)
serialized_rollback fixture is not available in TransactionTestCase.setUpClass
| Reported by: | Jacob Walls | Owned by: | Jacob Walls |
|---|---|---|---|
| Component: | Testing framework | Version: | 4.2 |
| Severity: | Normal | Keywords: | rollback emulation setUpClass TransactionTestCase |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
serialized_rollback=True allows subsequent TransactionTestCase classes to continue depending on the data created in the app's initial migration after a previous TransactionTestCase truncated tables.
By trial and error, I found that I couldn't depend on this emulated rollback during the setUpClass() phase, but rather during the setUp() phase only. This results in a difficult DX when debugging setUpClass() failures in tests that pass in isolation, and resorting to setUp() (as I ultimately did) has a performance penalty.
TestCase loads fixtures before running setUpClass(). Can we explore letting TransactionTestCase do the same? I imagine the refactor involves implementing TransactionTestCase.setUpClass().
Nothing in the docs advises that the emulated rollback is only available during certain parts of the test lifecycle, so at the very least I'd suggest a docs update. Happy to cross-post to forum if this isn't a "bug".
Sample project
models.py
from django.db import models
class MyModel(models.Model):
flag = models.BooleanField()
migrations/0001_initial.py
# Generated by Django 4.2.15 on 2024-08-06 19:34
from django.db import migrations, models
def seed_data(apps, schema_editor):
MyModel = apps.get_model("fooapp", "MyModel")
MyModel.objects.create(flag=True)
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="MyModel",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("flag", models.BooleanField()),
],
),
migrations.RunPython(seed_data, migrations.RunPython.noop),
]
tests.py
from django.test import TransactionTestCase
from .models import MyModel
def depend_on_fixture():
assert MyModel.objects.count()
class A(TransactionTestCase):
serialized_rollback = True
@classmethod
def setUpClass(cls):
depend_on_fixture()
def test_a(self):
pass
class B(TransactionTestCase):
serialized_rollback = True
@classmethod
def setUpClass(cls):
depend_on_fixture()
def test_b(self):
pass
Gives only one failure, which you'll miss if developing the tests in isolation:
======================================================================
ERROR: setUpClass (fooapp.tests.B)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jwalls/foo/fooapp/tests.py", line 25, in setUpClass
depend_on_fixture()
File "/Users/jwalls/foo/fooapp/tests.py", line 6, in depend_on_fixture
assert MyModel.objects.count()
AssertionError
----------------------------------------------------------------------
Ran 1 test in 0.004s
FAILED (errors=1)
Change History (10)
comment:1 by , 15 months ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:3 by , 14 months ago
| Patch needs improvement: | set |
|---|
comment:4 by , 14 months ago
| Patch needs improvement: | unset |
|---|
comment:5 by , 14 months ago
| Patch needs improvement: | set |
|---|
comment:6 by , 14 months ago
| Patch needs improvement: | unset |
|---|
comment:7 by , 14 months ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
comment:10 by , 12 months ago
#35921 is an issue that appeared with the fix for this ticket (unsure if this triggers a change in this ticket, or what flow is involved when an issue is found after a ticket is fixed)
Replicated on main thank you for the detailed report
We could class this as a new feature to add support for this but I do agree that it isn't intuitive and so will leave it as a bug