it-roy-ru.com

Отключить миграции при запуске модульных тестов в Django 1.7

Django 1.7 представил миграцию базы данных .

При запуске модульных тестов в Django 1.7 он вызывает migrate, что занимает много времени. Поэтому я хотел бы пропустить миграции Django и создать базу данных в конечном состоянии.

Я знаю, что игнорирование миграций может быть плохой практикой, так как эта часть кода не будет проверена. Но это не так: я выполняю полную миграцию на тестовом сервере CI (jenkins). Я только хочу пропустить миграции в моих локальных тестах, где скорость имеет значение.


Некоторый контекст:

До Django 1.6 при использовании South я использовал параметр SOUTH_TESTS_MIGRATE :

По умолчанию команда South syncdb также применяет миграции, если она запускается в неинтерактивном режиме, в том числе при выполнении тестов - она ​​будет запускать каждую миграцию каждый раз, когда вы запускаете свои тесты.

Если вы хотите, чтобы исполнитель тестов использовал syncdb вместо миграции, например, если ваши миграции слишком долго применяются, просто установите SOUTH_TESTS_MIGRATE = False в settings.py.

Однако syncdb больше не существует, теперь это migrate.

А из Django 1.8 я буду использовать параметр --keepdb:

Опцию --keepdb можно использовать для сохранения тестовой базы данных между запусками теста. Преимущество этого состоит в том, что вы пропускаете действия создания и уничтожения, что значительно сокращает время выполнения тестов, особенно в большом наборе тестов. Если тестовая база данных не существует, она будет создана при первом запуске, а затем сохранена для каждого последующего запуска. Любые непримененные миграции также будут применены к тестовой базе данных перед запуском тестового набора.

Так что этот вопрос ограничен Django 1.7.

102
David Arcos

Посмотрите на этот обходной путь , опубликованный Берни Самптионом в списке рассылки разработчиков 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 test

Эти дураки начинают думать, что приложение не мигрировало и т.д. каждый раз, когда создается тестовая база данных, она отражает текущую структура models.py.

В Django 1.9 эта ситуация несколько улучшена , и вы можете установить значение None:

MIGRATION_MODULES = {"myapp": нет}

75
albertgasset

Вот конец моего файла настроек:

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

на основании этого фрагмент

Я отключил миграции только во время выполнения тестов

68
Guillaume Vincent

Django-test-без миграции добавляет флаг --nomigrations к manage.py test. Работает как шарм.

26
rlmv

Update: не важно, это изменение было отменено до выхода финальной версии 1.10. Надеюсь, он вернется в следующей версии.


Обратите внимание, что с Django 1.10 это может контролироваться настройкой тестовой базы данных.

MIGRATE

По умолчанию: True

Если установлено значение False, Django не будет использовать миграции для создания тестовой базы данных.

3
Kevin Christopher Henry

https://Gist.github.com/apollovy/22826f493ad2d06d9a9a22464730ce0b

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

Для Django 1.9 и выше ответ Гийома Винсента больше не работает, поэтому вот новое решение:

Я использую этот фрагмент в моем файле настроек, после определения INSTALLED_APPS

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

Он перебирает все установленные приложения и помечает каждое как не имеющее модуля миграции. Смотрите Django документы для получения дополнительной информации .

Используя этот фрагмент, вы можете запускать свои тесты, устанавливая переменную окружения TESTS_WITHOUT_MIGRATIONS, например:

TESTS_WITHOUT_MIGRATIONS=1 ./manage.py test
1
devsnd

Я просто выясняю, как отключить миграции после Django 1.10, может быть, это может кому-то помочь. Вот ссылка на 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 и диктофон

Часть load_disk для модели миграции приложения, которая будет добавлена ​​в INSTALL_APP И часть recorder для подключения к базе данных Для версии до 1.9 нам нужно установить MIGRATION_MODULES={'do.not.migrate':'notmigrations'}, когда вы запускаете test Теперь нам нужно установить его Ничего подобного MIGRATION_MODULES={'do.not.migrate':None} Поэтому, если мы не хотим выполнять миграцию для какого-либо приложения, просто расширьте dict и верните None для функции getitem и сделайте то же самое в DATABASES, это то, что вам нужно сделать

PS: Для команды необходимо указать --setting=module.path.settings_test_snippet после testPPS Если вы работаете с pycharm, no не устанавливайте параметры --settings в Run/Debug configurations, просто добавьте путь settings_test_snippet.py в пользовательской настройке. Это просто хорошо !!

наслаждаться

0
FavorMylikes