在Django 1.7中运行单元测试时禁用迁移

Dav*_*cos 106 django unit-testing django-migrations

Django 1.7引入了数据库迁移.

在Django 1.7中运行单元测试时,它会强制迁移,这需要很长时间.所以我想跳过django迁移,并在最终状态下创建数据库.

我知道忽略迁移可能是一种不好的做法,因为代码的那部分将不会被测试.但事实并非如此:我正在CI测试服务器(jenkins)中运行完整的迁移.我只想跳过本地测试中的迁移,速度很重要.


一些背景:

直到Django 1.6,当使用South时,我使用了SOUTH_TESTS_MIGRATE设置:

默认情况下,如果South的syncdb命令以非交互模式运行(包括运行测试时),它还将应用迁移 - 每次运行测试时它都会运行每次迁移.

如果您希望测试运行器使用syncdb而不是迁移 - 例如,如果您的迁移需要太长时间才能应用 - 只需在settings.py中设置SOUTH_TESTS_MIGRATE = False即可.

但是,syncdb不再存在,现在它正在迁移.

从Django 1.8我将使用--keepdb参数:

--keepdb选项可用于在测试运行之间保留测试数据库.这样做的优点是可以跳过create和destroy操作,这大大减少了运行测试的时间,特别是在大型测试套件中.如果测试数据库不存在,它将在第一次运行时创建,然后为每次后续运行保留.在运行测试套件之前,任何未应用的迁移也将应用于测试数据库.

所以这个问题仅限于Django 1.7.

小智 78

看看这个解决方法,由Bernie Sumption发布到Django开发者邮件列表:

如果尚未运行makemigrations,则"migrate"命令会将应用视为未迁移,并直接从模型创建表,就像syncdb在1.6中所做的那样.我为单元测试定义了一个新的设置模块,称为"settings_test.py",它从主设置模块导入*并添加以下行:

MIGRATION_MODULES = {"myapp":"myapp.migrations_not_used_in_tests"}

然后我运行这样的测试:

DJANGO_SETTINGS_MODULE ="myapp.settings_test"python manage.py测试

这个傻瓜认为应用程序是未迁移的,因此每次创建测试数据库时它都会反映models.py的当前结构.

在Django 1.9中,这种情况有所改善,您可以将值设置为None:

MIGRATION_MODULES = {"myapp":无}

  • 从@ nealtodd的要点的评论中可以找到避免一些陷阱的解决方案的链接,并且非常简单:https://gist.github.com/NotSqrt/5f3c76cd15e40ef62d09 (21认同)
  • 请注意,``myapp.migrations_not_used_in_tests``模块不应存在. (9认同)
  • 在settings_test.py中动态构建MIGRATION_MODULES的函数要点:https://gist.github.com/nealtodd/2869341f38f5b1eeb86d (7认同)
  • 除了@bmihelac关于模块不存在的注释之外,模块字符串必须包含子字符串'migrations',为什么请参阅:https://github.com/django/django/blob/stable/1.7.x/django /db/migrations/loader.py#L76 (4认同)

Gui*_*ent 69

这是我的设置文件的结尾:

class DisableMigrations(object):

    def __contains__(self, item):
        return True

    def __getitem__(self, item):
        return None


TESTS_IN_PROGRESS = False
if 'test' in sys.argv[1:] or 'jenkins' in sys.argv[1:]:
    logging.disable(logging.CRITICAL)
    PASSWORD_HASHERS = (
        'django.contrib.auth.hashers.MD5PasswordHasher',
    )
    DEBUG = False
    TEMPLATE_DEBUG = False
    TESTS_IN_PROGRESS = True
    MIGRATION_MODULES = DisableMigrations()
Run Code Online (Sandbox Code Playgroud)

基于这个片段

我只在测试运行时禁用了迁移


小智 28

django-test-without-migrations--nomigrations为其添加了一个标志manage.py test.奇迹般有效.


LMB*_*LMB 8

从 Django 版本 3.1 及更高版本开始,执行此操作的正确方法是使用MIGRATE数据库设置字典中的设置。另请参阅文档

#settings.py
DATABASES = {
    'TEST': {
        'NAME': 'Foo',
        'MIGRATE': False
    }
}
Run Code Online (Sandbox Code Playgroud)