Мои модульные тесты Django занимают много времени для выполнения, таким образом, я ищу способы ускорить это. Я рассматриваю установку SSD, но я знаю, что это имеет его оборотные стороны также. Конечно, существуют вещи, которые я мог сделать со своим кодом, но я ищу структурную фиксацию. Даже запущение единственного теста является медленным, так как база данных должна быть восстановлена / юг мигрировал каждый раз. Таким образом, вот моя идея...
Так как я знаю, что тестовая база данных всегда будет довольно маленькой, почему я не могу только настроить систему, чтобы всегда сохранить всю тестовую базу данных в RAM? Никогда не касайтесь диска вообще. Как я настраиваю это в Django? Я предпочел бы продолжать использовать MySQL, так как это - то, что я использую в производстве, но если бы SQLite 3 или что-то еще делают это легким, я пошел бы тем путем.
SQLite или MySQL имеют опцию работать полностью в памяти? Должно быть возможно настроить псевдодиск и затем настроить тестовую базу данных, чтобы хранить ее данные там, но я не уверен, как сказать Django / MySQL использовать другой каталог данных для определенной базы данных, тем более, что это продолжает стираться и воссоздаваться каждое выполнение. (Я нахожусь на FWIW Mac.)
Если вы установите движок базы данных на sqlite3 при запуске тестов, Django будет использовать базу данных in-memory.
Я использую такой код в моем settings.py
, чтобы установить движок sqlite при запуске моих тестов:
if 'test' in sys.argv:
DATABASE_ENGINE = 'sqlite3'
Или в Django 1.2:
if 'test' in sys.argv:
DATABASES['default'] = {'ENGINE': 'sqlite3'}
И, наконец, в Django 1.3 и 1.4:
if 'test' in sys.argv:
DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}
(Полный путь к бэкенду не является строго необходимым в Django 1.3, но делает настройку совместимой. )
Вы также можете добавить следующую строку, если у вас возникли проблемы с миграцией на юг:
SOUTH_TESTS_MIGRATE = False
MySQL поддерживает механизм хранения под названием "MEMORY", который вы можете настроить в конфигурации вашей базы данных (settings.py
) следующим образом:
'USER': 'root', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'OPTIONS': {
"init_command": "SET storage_engine=MEMORY",
}
Обратите внимание, что механизм хранения MEMORY не поддерживает blob / текстовые колонки, так что если вы используете django.db.models.TextField
, это не будет работать для вас.
Я не могу ответить на ваш главный вопрос, но есть несколько вещей, которые вы можете сделать, чтобы ускорить работу.
Во-первых, убедитесь, что ваша база данных MySQL настроена на использование InnoDB. Тогда она может использовать транзакции для отката состояния базы данных перед каждым тестом, что, по моему опыту, приводит к значительному ускорению. Вы можете передать команду database init в вашем settings.py (синтаксис Django 1.2):
DATABASES = {
'default': {
'ENGINE':'django.db.backends.mysql',
'HOST':'localhost',
'NAME':'mydb',
'USER':'whoever',
'PASSWORD':'whatever',
'OPTIONS':{"init_command": "SET storage_engine=INNODB" }
}
}
Во-вторых, вам не нужно каждый раз запускать миграции South. Установите SOUTH_TESTS_MIGRATE = False
в вашем settings.py и база данных будет создана с помощью простого syncdb, что будет намного быстрее, чем выполнять все исторические миграции.