在Django 1.7中运行unit testing时禁用迁移
Django 1.7引入了数据库迁移 。
在Django 1.7中运行unit testing时,它会强制迁移 ,这需要很长时间。 所以我想跳过Django的迁移,并创build最终状态的数据库。
我知道忽略迁移可能是一个不好的做法,因为这部分代码不会被testing。 但事实并非如此:我在CItesting服务器上运行完整的迁移(jenkins)。 我只想跳过速度很重要的本地testing中的迁移。
一些背景:
直到Django 1.6 ,使用South时,我使用了SOUTH_TESTS_MIGRATE设置:
默认情况下,如果以非交互模式运行(包括运行testing时),则South的syncdb命令也将应用迁移 – 每次运行testing时都会运行每次迁移。
如果您希望testing运行程序使用syncdb而不是迁移 – 例如,如果您的迁移时间过长,则只需在settings.py中设置SOUTH_TESTS_MIGRATE = False即可。
但是, syncdb不再存在,现在正在迁移 。
从Django 1.8开始,我将使用–keepdb参数:
–keepdb选项可用于在testing运行之间保留testing数据库。 这具有跳过创build和销毁操作的优点,这大大减less了运行testing的时间,尤其是在大型testing套件中。 如果testing数据库不存在,则将在第一次运行时创build,然后保留以备后续运行。 在运行testing套件之前,任何未应用的迁移也将被应用到testing数据库。
所以这个问题仅限于Django 1.7。
看看这个解决方法 ,由Bernie Sumption发布到Django开发者邮件列表:
如果makemigrations尚未运行,那么“migrate”命令会将应用程序视为未迁移,并像1.6中的syncdb一样直接从模型创build表。 我为一个名为“settings_test.py”的unit testing定义了一个新的设置模块,它将从主设置模块中导入*并添加下面的代码:
MIGRATION_MODULES = {“myapp”:“myapp.migrations_not_used_in_tests”}
然后我运行这样的testing:
DJANGO_SETTINGS_MODULE =“myapp.settings_test”python manage.pytesting
这个傻子想到应用程序没有被移植,所以每次创build一个testing数据库时,都会反映出models.py的当前结构。
在Django 1.9中,这种情况有所改善 ,您可以将值设置为None
:
MIGRATION_MODULES = {“myapp”:无}
这是我的设置文件的结尾:
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()
基于这个片段
我只在testing运行时禁用迁移
django-test-without-migrations为manage.py test
添加了一个--nomigrations
标志。 奇迹般有效。
更新 :没关系,这个变化在1.10 final被释放之前被恢复了 。 希望它会在未来的版本中返回。
请注意,从Django 1.10开始,这可以通过testing数据库设置进行控制。
迁移
默认值:
True
如果设置为
False
,Django将不会使用迁移来创buildtesting数据库。
https://gist.github.com/apollovy/22826f493ad2d06d9a9a22464730ce0b
MIGRATION_MODULES = { app[app.rfind('.') + 1:]: 'my_app.migrations_not_used_in_tests' for app in INSTALLED_APPS }
对于Django 1.9而言,Guillaume Vincent的答案已经不再适用了,所以这里有一个新的解决scheme:
我在INSTALLED_APPS
的定义之后,在我的设置文件中使用了这个片段
if os.environ.get('TESTS_WITHOUT_MIGRATIONS', False): MIGRATION_MODULES = { app.split('.')[-1]: None for app in INSTALLED_APPS }
它遍历所有安装的应用程序,并将其标记为没有迁移模块。 有关更多信息,请参阅django文档 。
使用这个片段,你可以运行你的testing,设置环境variablesTESTS_WITHOUT_MIGRATIONS
,例如:
TESTS_WITHOUT_MIGRATIONS=1 ./manage.py test