Разные БД для тестирования в Django?
DATABASES = {
# 'default': {
# 'ENGINE': 'postgresql_psycopg2',
# ...
# }
# for unit tests
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'mydatabase'
}
}
у меня есть две базы данных: одна, которую я хотел бы использовать для модульных тестов, и одна для всего остального. Можно ли настроить это в Django 1.2.4?
(причина, по которой я спрашиваю, заключается в том, что с postgresql я получаю следующую ошибку:
foo@bar:~/path/$ python manage.py test
Creating test database 'default'...
Got an error creating the test database: permission denied to create database
Type 'yes' if you would like to try deleting the test database 'test_baz', or 'no' to cancel: yes
Destroying old test database...
Got an error recreating the test database: database "test_baz" does not exist
почему я могу получить эту ошибку? Думаю, мне все равно, всегда ли я могу использовать SQLite для модульных тестов, так как это отлично работает.)
8 ответов
в своем settings.py
(или local_settings.py
):
import sys
if 'test' in sys.argv:
DATABASES['default'] = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'mydatabase'
}
как я справляюсь с этим, имея несколько файлов настроек, так как я использую это для поддержания набора общих настроек с изменениями для каждого экземпляра. Это немного сложнее настроить, чем некоторые другие решения, но мне все равно нужно было это сделать, потому что я управлял немного разными настройками для локальной разработки, удаленной разработки, постановки и производства.
https://code.djangoproject.com/wiki/SplitSettings имеет несколько вариантов для управления настройками, и я выбрал практику, аналогичную описанной в https://code.djangoproject.com/wiki/SplitSettings#SimplePackageOrganizationforEnvironments
Итак, в моем каталоге проекта Django у меня есть папка настроек, которая выглядит так:
$ tree settings
settings
├── defaults.py
├── dev.py
├── dev.pyc
├── __init__.py
├── lettuce.py
├── travis.py
├── unittest.py
общие настройки находятся в settings/defaults.py и я импортирую их в Мои файлы настроек экземпляра. Так что ... settings/unittest.py выглядит так:
from defaults import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'my_database',
}
}
тогда, когда я хотите запустить тесты, я просто выполняю:
$ ./manage.py test --settings=settings.unittest
использовать sqlite для тестирования. Я буду использовать другой модуль настроек, если я хочу использовать другой тестовый бегун или конфигурацию базы данных.
это значительно ускорило выполнение теста.
import sys
if 'test' in sys.argv:
DATABASES['default'] = {
'ENGINE': 'django.db.backends.sqlite3',
'TEST_CHARSET': 'UTF8', # if your normal db is utf8
'NAME': ':memory:', # in memory
'TEST_NAME': ':memory:', # in memory
}
DEBUG = False # might accelerate a bit
TEMPLATE_DEBUG = False
from django.core.management import call_command
call_command('syncdb', migrate=True) # tables don't get created automatically for me
хотелось бы отметить, что вы можете указать тестовую базу данных уже в settings.py
. Видеть
https://docs.djangoproject.com/en/2.0/ref/settings/#test:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'USER': 'mydatabaseuser',
'NAME': 'mydatabase',
'TEST': {
'NAME': 'mytestdatabase',
},
},
}
Если у вас есть доступ к ручному созданию базы данных, вы можете использовать Джанго-нос как ваш TEST_RUNNER. После установки, если вы передадите следующую переменную среды, она не будет удалять и повторно создавать базу данных.
REUSE_DB=1 ./manage.py test
вы также можете добавить следующее settings.py таким образом, вам не нужно писать REUSE_DB=1 каждый раз, когда вы хотите запустить тесты:
os.environ['REUSE_DB'] = "1"
Примечание: это также оставит все ваши таблицы в базах данных, что означает настройка теста будет немного быстрее, но вам придется вручную обновить таблицы (или удалить и повторно создать базу данных самостоятельно) при изменении модели.
хотя это уже решаемо...
Если ваша база данных для тестов - это обычная БД:
Я думаю, что вы не делаете модульный тест, так как вы полагаетесь на базу данных. Во всяком случае, django содержит тестовый тип для этого (не унитарный): django.test.TestCase
вам нужно вывести из django.test.TestCase
вместо unittest.TestCase
это создаст для вас новую базу данных rehershal, которая будет уничтожена при завершении теста.
есть интересные объяснения / советы по тестированию с БД по следующей ссылке
Тестирование Приложений Django
Почему я могу получить эту ошибку?
из-за недостаточных разрешений. Вы можете изменить разрешения пользователя с помощью ALTER USER username CREATEDB;
после psql
с привилегиями суперпользователя.
например,
$ sudo su - postgres
$ psql
psql (9.3.18)
Type "help" for help.
postgres=# ALTER USER username CREATEDB;
ALTER ROLE
Я решил эту проблему, просто создав другие константы настроек DATABASES_AVAILABLE
.
DATABASES_AVAILABLE = {
'main': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'nep',
'USER': 'user',
'PASSWORD': 'passwd',
'HOST': 'localhost',
},
'remote': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'nes_dev',
'USER': 'usr',
'PASSWORD': 'passwd',
'HOST': '200.144.254.136',
},
'sqlite': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
}
# This solves the problem with tests
# Define a system variable called DJANGO_DATABASE_TEST and set it to the
# the database you want
database = os.environ.get('DJANGO_DATABASE_TEST', 'main')
DATABASES = {
'default': DATABASES_AVAILABLE[database]
}