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

时间:2017-05-02 07:22:21

标签: python django unit-testing

我试过写a test on specific migration files。基本上我想测试一对迁移之间的数据库和数据的当前状态。我使用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)

我们在项目中有很多迁移文件,因此使用单元测试运行所有迁移文件需要花费大量时间。通常,我会将迁移模块设置为None

中的settings_test.py
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(作为{{1} }})。

我正在考虑压缩前89个迁移并将结果与​​self.migrate_to0090一起放在一个单独的文件夹中,然后在测试中引用该迁移文件夹。但是,我不确定这是否是一个很好的解决方案。

1 个答案:

答案 0 :(得分:0)

这是我目前所理解的,如果我不对,请指导我。

问题

  1. Migration test code需要应用迁移。
  2. Django的开始时间早于@override_settingsetUpClass()
  3. 等任何其他流程

    解决方案

    在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()
      
    4. 试用信息

        关于TestClass或TestMethod的
      1. @override_setting 无法正常工作,因为Django在@override_setting装修
      2. 之前启动并运行迁移
      3. pytest-django --nomigrations 不工作不太确定,但我的解决方法是禁用从Django设置迁移而不是pytest-django