如何在Django中更快地测试迁移?

3
我尝试编写特定迁移文件的测试。基本上,我想测试一对迁移之间数据库和数据的当前状态。我使用MigrationExecutor如下:
executor = MigrationExecutor(connection)
old_apps = executor.loader.project_state(self.migrate_from).apps
executor.migrate(self.migrate_from)
# do something here
executor.migrate(self.migrate_to)

我们的项目中有很多迁移文件,因此运行所有这些文件的单元测试需要很长时间。通常,我会在settings_test.py中将迁移模块设置为None
MIGRATION_MODULES: {
    'my_app': None
}

使用这个设置,测试将会运行得非常快。问题是无法找到用于测试的迁移文件(self.migrate_fromself.migrate_to)。
django.db.migrations.exceptions.NodeNotFoundError: Node ('poleluxe', '0090_auto_previous_migration') not a valid node

所以我不得不在测试中再次包含迁移模块。
有没有一种方法可以在不运行所有迁移文件的情况下包含迁移文件?在我的情况下,我想跳过从00010089的所有迁移,仅运行0090(作为self.migration_from)和0091(作为self.migrate_to)。
我考虑压缩前89个迁移并将结果放在一个单独的文件夹中,与00900091一起引用该迁移文件夹进行测试。但是,我不确定这是否是一个好的解决方案。

你有没有读过这篇关于这种测试的文章:https://www.caktusgroup.com/blog/2016/02/02/writing-unit-tests-django-migrations/? - undefined
是的。实际上,我已经在帖子中包含了那个。 - undefined
1个回答

0

这是我目前的理解,请在我理解错误时指导我。

问题

  1. 迁移测试代码需要应用迁移。
  2. Django比任何其他进程(如@override_settingsetUpClass())更早启动。

解决方案

在TestClass的最开始处覆盖MIGRATION_MODULES设置,即使TestClass尚未完全初始化,因为那是我找到的唯一正确的位置。

通过这种方式,不仅可以在运行测试时禁用所有迁移以加快速度,还可以测试迁移文件。

  1. 禁用所有来自settings.py的迁移。

    MIGRATION_MODULES = {app: None for app in INSTALLED_APPS}
    
  2. (可选) 如果您使用pytest-django,请从pytest设置中删除--nomigrations选项。
  3. 覆盖'MIGRATION_MODULES'设置,并在测试后将其设置回原始值。

    class TestMigrations(TestCase):
        origin_modules = getattr(settings, 'MIGRATION_MODULES', {})
        setattr(settings, 'MIGRATION_MODULES', {})    
    
        ...
    
        @classmethod
        def tearDownClass(cls):
            setattr(settings, 'MIGRATION_MODULES', cls.origin_modules)
            super().tearDownClass()
    

试用信息

  1. @override_setting 在 TestClass 或 TestMethod 上不起作用,因为 Django 在运行迁移之前就开始启动和运行了@override_setting修饰
  2. pytest-django 使用 --nomigrations 不起作用,不太确定,但我的解决方法是在 Django 设置中禁用迁移而不是 pytest-django

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接