Data migration only executed for the first test
Asked Answered
B

1

8

I have a simple data migration, which creates a Group, and which looks like this :

def make_manager_group(apps, schema_editor):
    Group = apps.get_model("auth", "Group")
    managers_group = Group(name="managers")
    managers_group.save()

class Migration(migrations.Migration):

    dependencies = [
        ('my_app', '0001_initial'),
        ('auth', '0006_require_contenttypes_0002'),
    ]

    operations = [
        migrations.RunPython(make_manager_group, reverse_code=lambda *args, **kwargs: True)
    ]

and a simple functional test app containing the following tests :

from django.contrib.auth.models import Group
from django.contrib.staticfiles.testing import StaticLiveServerTestCase

class FunctionalTest(StaticLiveServerTestCase):

    def setUp(self):
        print("Groups : {}".format(Group.objects.all()))

    def test_2(self):
        pass

    def test_1(self):
        pass

When I run the tests, I get :

Creating test database for alias 'default'...
Groups : [<Group: managers>]
.Groups : []
.

Clearly, the group is being created when the test db is created, but when this db is reset between tests, it is reset to an empty db and not to the state it was after all the migrations were applied.

The model itself doesn't contain anything special (I only created one for the migration not to be the first, as in the project I'm working on, but I'm not sure it is needed at all).

Is this a bug, or am I missing something about data migration, to be able to have my group created when every single test starts?

Edit 1 : I'm using Django 1.8.3

Edit 2 : Quick'n'dirty hack added to the setUp of the test class :

    from django.contrib.auth.models import Group, Permission
    if not Group.objects.all():
        managers_group = Group(name="managers")
        managers_group.save()
        managers_group.permissions.add(
            Permission.objects.get(codename='add_news'),
            Permission.objects.get(codename='change_news'),
            Permission.objects.get(codename='delete_news')
        )

This is all but DRY, but until now, I couldn't find another way...

Bruges answered 13/8, 2015 at 14:47 Comment(0)
B
6

I answer my own question :

It seems to be a filed bug which has became documented

It says that using TransactionTestCase and its subclasses (like in my case LiveServerTestCase) doesn't insert the data migrations before every test. It is just done once for the first of them.

It also says that we could set serialized_rollback to True, which should force the rollback to the filled database. But in my case, I'm having the same error as the last message in the bug report.

So I'm going to stick with my dirty hack for now, and maybe create a data fixture, as it says that fixtures are used everytime.

Bruges answered 14/8, 2015 at 10:45 Comment(2)
Wow seems to still be an issue in django 2.0Burnett
I confirm I solved this problem by adding serialized_rollback = True in test class (django 2.1), thank you @BrugesSex

© 2022 - 2024 — McMap. All rights reserved.