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

姜戈 1.7介绍了 数据库迁移

在 Django 1.7中运行单元测试时,它强制使用 迁徙,这需要很长时间。因此,我希望跳过 django 迁移,并在最终状态下创建数据库。

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


一些背景:

在使用 South 之前,我一直使用 < em > SOTH _ TESTS _ MIGRATE 设置:

默认情况下,如果在非交互模式下运行,South 的 syncdb 命令也会应用迁移,包括运行测试时——每次运行测试时,它都会运行每次迁移。

如果您希望测试运行程序使用 syncdb 而不是 shift (例如,如果您的迁移花费了太长的时间来应用) ,只需在 setings.py 中设置 SOUTH _ TESTS _ MIGRATE = False。

然而,Syncdb不再存在了,现在它是 迁徙

在 Django 1.8中,我将使用 --keepdb参数:

Keepdb 选项可用于在测试运行之间保留测试数据库。这样做的好处是,可以跳过创建和销毁操作,从而大大减少运行测试的时间,特别是大型测试套件中的测试。如果测试数据库不存在,它将在第一次运行时创建,然后为每次后续运行保留。在运行测试套件之前,任何未应用的迁移也将应用到测试数据库。

So this question is limited to Django 1.7.

34509 次浏览

看看由 Bernie Sumtion 发布在 Django 开发者邮件列表上的 this workaround:

如果 make 移民尚未运行,则“ ”命令會處理 an app as unmigrated, and creates tables directly from the models just 像 syncdb 在1.6中所做的那样。我为单元定义了一个新的设置模块 名为“ sets _ test.py”的测试,它从 main 中导入 * 设置模块并添加以下代码行:

MIGRATION _ MODULES = {“ myapp”: “ myapp.Migations _ not _ used _ in _ test”}

然后我做这样的测试:

DJANGO _ SETTING _ MODULE = “ myapp.sets _ test”python management. py test

这些傻瓜认为这个应用程序没有被移植过,等等 every time a test database is created it reflects the current 模型的结构。

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

MIGRATION _ MODULES = {“ myapp”: None }

Here is the end of my settings file :

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

基于这个 片段

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

Django-test-without-mobile manage.py test添加了一个 --nomigrations标志。

Https://gist.github.com/apollovy/22826f493ad2d06d9a9a22464730ce0b

MIGRATION_MODULES = {
app[app.rfind('.') + 1:]: 'my_app.migrations_not_used_in_tests'
for app in INSTALLED_APPS
}

更新 : 没关系,这个更改是在1.10决赛发布之前的 恢复了版本,希望在以后的版本中能够再次出现。


Note that as of Django 1.10 this can be controlled by a test database setting.

移民

默认值: True

如果设置为 False,Django 将不会使用迁移来创建测试数据库。

对于 django 1.9及以上版本,Guillaume Vincent 的答案不再适用,所以这里有一个新的解决方案:

INSTALLED_APPS的定义之后,我将在设置文件中使用这个代码片段

if os.environ.get('TESTS_WITHOUT_MIGRATIONS', False):
MIGRATION_MODULES = {
app.split('.')[-1]: None for app in INSTALLED_APPS
}

它遍历所有已安装的应用程序,并将每个应用程序标记为没有迁移模块。

使用这个代码片段,你可以运行你的测试,设置环境变量 TESTS_WITHOUT_MIGRATIONS,例如:

TESTS_WITHOUT_MIGRATIONS=1 ./manage.py test

我刚想出如何在 django 1.10之后禁用迁移,也许对某些人有帮助。这里是 链接 at git

class DisableMigrations(dict):
def __contains__(self, item):
return True


def __getitem__(self, item):
return None


DATABASES = DisableMigrations()


MIGRATION_MODULES = DisableMigrations()

Django 1.10的迁移分为两部分,请查看 Load _ disk录音机

INSTALL_APP上添加的应用程序迁移模型的 load_disk部分 以及 recorder中用于数据库连接的部分 对于1.9之前的版本,我们需要在运行测试时设置 MIGRATION_MODULES={'do.not.migrate':'notmigrations'} 现在我们需要设置它,没有像 MIGRATION_MODULES={'do.not.migrate':None} 因此,如果我们不希望为任何应用程序进行迁移,只需扩展一个 dict 并为 getitem函数返回 None,并在 DATABASES上进行相同的操作,这就是您需要做的正确事情

PS: 对于 command,需要在 test之后指定 --setting=module.path.settings_test_snippet PPS 如果使用 pycharm不要Run/Debug configurations设置 --settings选项,只需在自定义设置中添加 settings_test_snippet.py的路径。没事的!

好好享受

从 Django 版本3.1开始,正确的方法是使用数据库设置中的 MIGRATE设置。参见 文件

#settings.py
DATABASES = {
'TEST': {
'NAME': 'Foo',
'MIGRATE': False
}
}