仅在第一次测试时执行数据迁移

Posted

技术标签:

【中文标题】仅在第一次测试时执行数据迁移【英文标题】:Data migration only executed for the first test 【发布时间】:2015-11-06 14:50:30 【问题描述】:

我有一个简单的数据迁移,它创建了一个Group,看起来像这样:

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)
    ]

以及一个包含以下测试的简单功能测试应用程序:

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

当我运行测试时,我得到:

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

显然,该组是在创建测试数据库时创建的,但是当在测试之间重置此数据库时,它会重置为空数据库,而不是应用所有迁移后的状态。

模型本身不包含任何特殊的东西(我只是为迁移而不是第一个创建了一个,就像在我正在处理的项目中一样,但我不确定是否需要它)。

这是一个错误,还是我错过了有关数据迁移的某些内容,以便能够在每个测试开始时创建我的组?

编辑 1:我使用的是 Django 1.8.3

编辑 2: Quick'n'dirty hack 添加到测试类的设置中:

    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')
        )

这只是 DRY,但直到现在,我找不到其他方法......

【问题讨论】:

【参考方案1】:

我回答我自己的问题:

好像是filed bug 变成了documented

它表示使用TransactionTestCase 及其子类(例如在我的情况下为LiveServerTestCase)不会在每次测试之前插入数据迁移。他们中的第一个只完成一次。

它还说我们可以将serialized_rollback 设置为True,这应该会强制回滚到已填充的数据库。但就我而言,我遇到的错误与错误报告中的最后一条消息相同。

所以我现在要坚持我的肮脏技巧,也许会创建一个数据夹具,因为它说每次都会使用夹具。

【讨论】:

哇似乎仍然是django 2.0中的一个问题 我确认我通过在测试类(django 2.1)中添加serialized_rollback = True 解决了这个问题,谢谢@BriceP

以上是关于仅在第一次测试时执行数据迁移的主要内容,如果未能解决你的问题,请参考以下文章

使用 Docker-Compose 时如何执行 Django 数据库迁移?

Laravel Dusk:迁移和种子测试数据库一次

Flyway 没有正确清理数据库,执行了两次迁移文件

仅 IOS 8 中的核心数据迁移问题,而不是 IOS 9

轻量级迁移后核心数据执行动作

迁移到 JDK 11 后 Spring Boot 测试中的 Mockito 错误