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'