Как запустить тесты для приложения для повторного использования django?
Могу ли я запускать тесты для своего многоразового приложения Django без включения этого приложения в проект?
В моем приложении используются некоторые модели, поэтому необходимо предоставить настройки (TEST_)DATABASE_*
. Где я должен хранить их и как мне запускать тесты?
Для проекта Django я могу запускать тесты с помощью manage.py test
; когда я использую django-admin.py test
с моим автономным приложением, я получаю:
Ошибка: настройки не могут быть импортированы, потому что переменная среды DJANGO_SETTINGS_MODULE undefined.
Каковы лучшие практики здесь?
Ответы
Ответ 1
Я закончил с таким решением (он был вдохновлен решением, найденным в django-голосовании):
Создать файл, например. 'runtests.py' в файле dir, содержащий:
import os, sys
from django.conf import settings
DIRNAME = os.path.dirname(__file__)
settings.configure(DEBUG = True,
DATABASE_ENGINE = 'sqlite3',
DATABASE_NAME = os.path.join(DIRNAME, 'database.db'),
INSTALLED_APPS = ('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
'myapp',
'myapp.tests',))
from django.test.simple import run_tests
failures = run_tests(['myapp',], verbosity=1)
if failures:
sys.exit(failures)
Он позволяет запускать тесты командой python runtests.py
.
Он не требует установленных зависимостей (например, buildout), и это не вредит испытаниям, когда приложение включено в более крупный проект.
Ответ 2
Правильное использование тестового бегуна Django ( >= 1.4) выглядит следующим образом:
import django, sys
from django.conf import settings
settings.configure(DEBUG=True,
DATABASES={
'default': {
'ENGINE': 'django.db.backends.sqlite3',
}
},
ROOT_URLCONF='myapp.urls',
INSTALLED_APPS=('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
'myapp',))
try:
# Django <= 1.8
from django.test.simple import DjangoTestSuiteRunner
test_runner = DjangoTestSuiteRunner(verbosity=1)
except ImportError:
# Django >= 1.8
django.setup()
from django.test.runner import DiscoverRunner
test_runner = DiscoverRunner(verbosity=1)
failures = test_runner.run_tests(['myapp'])
if failures:
sys.exit(failures)
DjangoTestSuiteRunner и DiscoverRunner имеют в основном совместимые интерфейсы.
Для получения дополнительной информации обратитесь к документам "Определение тестового Runner":
Ответ 3
Для Django 1.7 он немного отличается. Предполагая, что у вас есть следующее
структура каталога для приложения foo
:
foo
|── docs
|── foo
│ ├── __init__.py
│ ├── models.py
│ ├── urls.py
│ └── views.py
└── tests
├── foo_models
│ ├── __init__.py
│ ├── ...
│ └── tests.py
├── foo_views
│ ├── __init__.py
│ ├── ...
│ └── tests.py
├── runtests.py
└── urls.py
Таким образом, сам проект Django структурирует свои тесты.
Вы хотите выполнить все тесты в foo/tests/
с помощью команды:
python3 runtests.py
Вы также хотите иметь возможность запускать команду из родительского каталога tests
, например. Tox или Invoke, так же, как python3 foo/tests/runtests.py
.
Решение, представленное здесь, довольно многократно используется, нужно только настроить имя приложения foo
(и, при необходимости, дополнительные приложения). Они не могут быть установлены с помощью modify_settings, поскольку это пропустит настройку базы данных.
Необходимы следующие файлы:
urls.py
"""
This urlconf exists because Django expects ROOT_URLCONF to exist. URLs
should be added within the test folders, and use TestCase.urls to set them.
This helps the tests remain isolated.
"""
urlpatterns = []
runtests.py
#!/usr/bin/env python3
import glob
import os
import sys
import django
from django.conf import settings
from django.core.management import execute_from_command_line
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
sys.path.append(os.path.abspath(os.path.join(BASE_DIR, '..')))
# Unfortunately, apps can not be installed via ``modify_settings``
# decorator, because it would miss the database setup.
CUSTOM_INSTALLED_APPS = (
'foo',
'django.contrib.admin',
)
ALWAYS_INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
ALWAYS_MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
settings.configure(
SECRET_KEY="django_tests_secret_key",
DEBUG=False,
TEMPLATE_DEBUG=False,
ALLOWED_HOSTS=[],
INSTALLED_APPS=ALWAYS_INSTALLED_APPS + CUSTOM_INSTALLED_APPS,
MIDDLEWARE_CLASSES=ALWAYS_MIDDLEWARE_CLASSES,
ROOT_URLCONF='tests.urls',
DATABASES={
'default': {
'ENGINE': 'django.db.backends.sqlite3',
}
},
LANGUAGE_CODE='en-us',
TIME_ZONE='UTC',
USE_I18N=True,
USE_L10N=True,
USE_TZ=True,
STATIC_URL='/static/',
# Use a fast hasher to speed up tests.
PASSWORD_HASHERS=(
'django.contrib.auth.hashers.MD5PasswordHasher',
),
FIXTURE_DIRS=glob.glob(BASE_DIR + '/' + '*/fixtures/')
)
django.setup()
args = [sys.argv[0], 'test']
# Current module (``tests``) and its submodules.
test_cases = '.'
# Allow accessing test options from the command line.
offset = 1
try:
sys.argv[1]
except IndexError:
pass
else:
option = sys.argv[1].startswith('-')
if not option:
test_cases = sys.argv[1]
offset = 2
args.append(test_cases)
# ``verbosity`` can be overwritten from command line.
args.append('--verbosity=2')
args.extend(sys.argv[offset:])
execute_from_command_line(args)
Некоторые параметры являются необязательными; они улучшают скорость или более реалистичную среду.
Второй аргумент указывает на текущий каталог. Он использует функцию для предоставления пути к каталогу для обнаружения тестов ниже этого каталога.
Ответ 4
Для моего многоразового приложения (django-moderation) Я использую buildout. Я создаю example_project
, я использую его с buildout для запуска тестов на нем. Я просто помещаю свое приложение в настройки example_project
.
Когда я хочу установить все зависимости, используемые моим проектом и запускать тесты, мне нужно сделать следующее:
Здесь вы можете найти руководство по настройке приложения многократного использования для использования buildout для развертывания и запуска тестов: http://jacobian.org/writing/django-apps-with-buildout/
Здесь вы найдете пример buildout config, который я использую в своем проекте:
http://github.com/dominno/django-moderation/blob/master//buildout.cfg