Django unit test без создания тестовой базы данных каждый раз, когда я запускаю
Кажется, что "manage.py test" создает тестовую базу данных каждый раз, когда я запускаю тест. Есть ли способ предотвратить создание тестовой базы данных каждый раз, когда я запускаю тест, но просто усекаю данные (flush)?
Мои таблицы составляют почти около 40 таблиц (даже для одного приложения, а не для всего проекта), и заставляет меня болеть каждый раз, когда я запускаю тест.
Ответы
Ответ 1
В зависимости от ваших потребностей у вас есть несколько вариантов:
Ответ 2
Из Django 1.8 вы можете использовать флаг -keepdb при вызове manage.py
Новое в Django 1.8: вы можете запретить тестовые базы данных уничтожен, добавив флаг - keepdb в тестовую команду. Это будет сохранить тестовую базу данных между прогонами. Если база данных не существует, он будет сначала создан. Любые миграции также будут применены чтобы поддерживать его в актуальном состоянии. (https://docs.djangoproject.com/en/1.8/topics/testing/overview/#the-test-database)
Таким образом, ваш вызов может выглядеть следующим образом:
python manage.py test --keepdb
Или используя сокращенное -k это может выглядеть так:
python manage.py test -k
Ответ 3
django-нос поддерживает повторное использование базы данных:
https://github.com/django-nose/django-nose#enabling-database-reuse
Однако не забудьте прочитать комментарии:
Новая морщина заключается в том, что всякий раз, когда ваша схема БД изменяется, вы должен оставить флаг при следующем запуске тестов. Это приведет к тестовый бегун для повторной инициализации тестовой базы данных.
Кроме того, REUSE_DB несовместим с TransactionTestCases, которые уходят мусор в БД, поэтому не забудьте сделать ваш TransactionTestCases гигиеничным (см. ниже), если вы хотите использовать его.
Ответ 4
Следующее решение также уменьшит время создания db, если число южных миграций больше. Во время модульного тестирования запуск syncdb вместо запуска всех южных миграций будет намного быстрее.
SOUTH_TESTS_MIGRATE = False # Чтобы отключить миграцию и использовать syncdb вместо
Ответ 5
Я предполагаю, что это не лучшая практика, но что-то, что я сделал в качестве обходного пути, - это создать несколько различных тестовых программ в каталоге управления/команд в приложении.
https://docs.djangoproject.com/en/1.7/howto/custom-management-commands/
Например, я сейчас работаю над приложением, которое требует некоторых усовершенствованных функций Postgres (не может использовать Sqlite), поэтому вместо создания тестовых функций как части test.py, я создал test_process.py в myapp/management/commands/
Ответ 6
Возможно, вы захотите иметь pytest
как тестовый бегун. Ниже приведен пример конфигурации.
Пример файла pytest.ini
:
[pytest]
norecursedirs=
*.egg
.git
.tox
.env
_sass
build
dist
migrations
fabfile
.tox
python_files =
test_*.py
tests.py
DJANGO_SETTINGS_MODULE=settings.dev
addopts=
--reuse-db
--nomigrations
--cov=your_app
--ignore=.tox
--ignore=fabfile
--ignore=scripts
--ignore=settings
--ignore=tmp
--cov-report=html
--cov-report=term
--cov-report=annotate
Пример runtests.py
файла:
#!/usr/bin/env python
import os
import sys
import pytest
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.dev")
return pytest.main()
if __name__ == '__main__':
sys.exit(main())
Пример requirements.txt
file:
pytest==3.0.2
pytest-django==2.9.1
pytest-cov==2.2.1
Запустите тесты:
./runtests.py
Обратите внимание: этот эффект достигается с помощью директив reuse-db
и nomigrations
.
Ответ 7
Вы можете попробовать с бегуном
Пример:
Сначала создайте test_runners.py
from django.test.runner import DiscoverRunner
class NoDbTestRunner(DiscoverRunner):
def setup_databases(self, **kwargs):
""" Override the database creation defined in parent class """
pass
def teardown_databases(self, old_config, **kwargs):
""" Override the database teardown defined in parent class """
pass
Тогда объявите выше бегуна в settings.py
TEST_RUNNER = 'api.tests.test_runners.NoDbTestRunner'