Расширенные темы тестирования¶
Фабрика запросов¶
-
class
RequestFactory
[исходный код]¶
Фабрика RequestFactory
использует тот же API, что и тестовый клиент. Однако вместо того, чтобы вести себя как браузер, RequestFactory предоставляет способ создания экземпляра запроса, который может быть использован в качестве первого аргумента любого представления. Это означает, что вы можете тестировать функцию представления так же, как и любую другую функцию - как черный ящик, с точно известными входами, тестируя определенные выходы.
API для RequestFactory
является слегка ограниченным подмножеством API тестового клиента:
- Он имеет доступ только к HTTP методам
get()
,post()
,put()
,delete()
,head()
,options()
иtrace()
. - Эти методы принимают все те же аргументы, за исключением
follow
. Поскольку это просто фабрика для создания запросов, обработка ответа зависит от вас. - Оно не поддерживает промежуточное программное обеспечение. Атрибуты сессии и аутентификации должны быть предоставлены самим тестом, если это необходимо для правильной работы представления.
Пример¶
Ниже приведен модульный тест, использующий фабрику запросов:
from django.contrib.auth.models import AnonymousUser, User
from django.test import RequestFactory, TestCase
from .views import MyView, my_view
class SimpleTest(TestCase):
def setUp(self):
# Every test needs access to the request factory.
self.factory = RequestFactory()
self.user = User.objects.create_user(
username='jacob', email='jacob@…', password='top_secret')
def test_details(self):
# Create an instance of a GET request.
request = self.factory.get('/customer/details')
# Recall that middleware are not supported. You can simulate a
# logged-in user by setting request.user manually.
request.user = self.user
# Or you can simulate an anonymous user by setting request.user to
# an AnonymousUser instance.
request.user = AnonymousUser()
# Test my_view() as if it were deployed at /customer/details
response = my_view(request)
# Use this syntax for class-based views.
response = MyView.as_view()(request)
self.assertEqual(response.status_code, 200)
AsyncRequestFactory¶
RequestFactory
создает WSGI-подобные запросы. Если вы хотите создавать ASGI-подобные запросы, включая наличие корректного ASGI scope
, вы можете вместо этого использовать django.test.AsyncRequestFactory
.
Этот класс напрямую API-совместим с RequestFactory
, с той лишь разницей, что он возвращает экземпляры ASGIRequest
, а не WSGIRequest
. Все его методы по-прежнему являются синхронными callables.
Тестирование представлений на основе классов¶
Для тестирования представлений на основе классов вне цикла запрос/ответ вы должны убедиться, что они настроены правильно, вызвав setup()
после инстанцирования.
Например, предположим следующее представление на основе классов:
from django.views.generic import TemplateView
class HomeView(TemplateView):
template_name = 'myapp/home.html'
def get_context_data(self, **kwargs):
kwargs['environment'] = 'Production'
return super().get_context_data(**kwargs)
Вы можете напрямую протестировать метод get_context_data()
, сначала инстанцировав представление, затем передав request
в setup()
, прежде чем перейти к коду вашего теста:
from django.test import RequestFactory, TestCase
from .views import HomeView
class HomePageTest(TestCase):
def test_environment_set_in_context(self):
request = RequestFactory().get('/')
view = HomeView()
view.setup(request)
context = view.get_context_data()
self.assertIn('environment', context)
Тесты и несколько имен хостов¶
Настройка ALLOWED_HOSTS
проверяется при запуске тестов. Это позволяет тестовому клиенту различать внутренние и внешние URL.
Проекты, которые поддерживают многопользовательскую аренду или иным образом изменяют бизнес-логику на основе хоста запроса и используют пользовательские имена хостов в тестах, должны включать эти хосты в ALLOWED_HOSTS
.
Первый способ сделать это - добавить хосты в файл настроек. Например, набор тестов для docs.djangoproject.com включает следующее:
from django.test import TestCase
class SearchFormTestCase(TestCase):
def test_empty_get(self):
response = self.client.get('/en/dev/search/', HTTP_HOST='docs.djangoproject.dev:8000')
self.assertEqual(response.status_code, 200)
и файл настроек включает список доменов, поддерживаемых проектом:
ALLOWED_HOSTS = [
'www.djangoproject.dev',
'docs.djangoproject.dev',
...
]
Другой вариант - добавить необходимые хосты к ALLOWED_HOSTS
, используя override_settings()
или modify_settings()
. Этот вариант может быть предпочтительным в автономных приложениях, которые не могут упаковать свой собственный файл настроек, или в проектах, где список доменов не статичен (например, поддомены для мультитенансинга). Например, вы можете написать тест для домена http://otherserver/
следующим образом:
from django.test import TestCase, override_settings
class MultiDomainTestCase(TestCase):
@override_settings(ALLOWED_HOSTS=['otherserver'])
def test_other_domain(self):
response = self.client.get('http://otherserver/foo/bar/')
Отключение проверки ALLOWED_HOSTS
(ALLOWED_HOSTS = ['*']
) при выполнении тестов предотвращает выдачу тестовым клиентом полезного сообщения об ошибке, если вы следуете перенаправлению на внешний URL.
Тесты и многочисленные базы данных¶
Тестирование конфигураций основной/реплики¶
Если вы тестируете конфигурацию из нескольких баз данных с репликацией первичной/репликативной (в некоторых базах данных называемой ведущей/ведомой), такая стратегия создания тестовых баз данных создает проблему. Когда создаются тестовые базы данных, репликации не будет, и в результате данные, созданные на основной базе данных, не будут видны на реплике.
Чтобы компенсировать это, Django позволяет вам определить, что база данных является тестовым зеркалом. Рассмотрим следующий (упрощенный) пример конфигурации базы данных:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myproject',
'HOST': 'dbprimary',
# ... plus some other settings
},
'replica': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myproject',
'HOST': 'dbreplica',
'TEST': {
'MIRROR': 'default',
},
# ... plus some other settings
}
}
В этой установке у нас есть два сервера баз данных: dbprimary
, описанный псевдонимом базы данных default
, и dbreplica
, описанный псевдонимом replica
. Как и следовало ожидать, dbreplica
был настроен администратором базы данных как копия для чтения dbprimary
, поэтому при нормальной работе любая запись на default
будет отображаться на replica
.
Если бы Django создал две независимые тестовые базы данных, это нарушило бы все тесты, которые ожидали репликации. Однако, база данных replica
была настроена как тестовое зеркало (с помощью настройки MIRROR
), что указывает на то, что при тестировании база данных replica
должна рассматриваться как зеркало базы данных default
.
Когда тестовая среда настроена, тестовая версия replica
не будет создана. Вместо этого соединение с replica
будет перенаправлено на default
. В результате записи в default
будут появляться в replica
- но потому, что они фактически являются одной и той же базой данных, а не потому, что между этими двумя базами данных существует репликация данных.
Управление порядком создания тестовых баз данных¶
По умолчанию Django предполагает, что все базы данных зависят от базы данных default
и поэтому всегда создает базу данных default
первой. Однако не гарантируется порядок создания любых других баз данных в вашей тестовой установке.
Если конфигурация вашей базы данных требует определенного порядка создания, вы можете указать существующие зависимости с помощью тестовой настройки DEPENDENCIES
. Рассмотрим следующий (упрощенный) пример конфигурации базы данных:
DATABASES = {
'default': {
# ... db settings
'TEST': {
'DEPENDENCIES': ['diamonds'],
},
},
'diamonds': {
# ... db settings
'TEST': {
'DEPENDENCIES': [],
},
},
'clubs': {
# ... db settings
'TEST': {
'DEPENDENCIES': ['diamonds'],
},
},
'spades': {
# ... db settings
'TEST': {
'DEPENDENCIES': ['diamonds', 'hearts'],
},
},
'hearts': {
# ... db settings
'TEST': {
'DEPENDENCIES': ['diamonds', 'clubs'],
},
}
}
При такой конфигурации база данных diamonds
будет создана первой, так как это единственный псевдоним базы данных без зависимостей. Далее будут созданы псевдонимы default
и clubs
(хотя порядок создания этой пары не гарантирован), затем hearts
и, наконец, spades
.
Если в определении DEPENDENCIES
есть какие-либо круговые зависимости, будет вызвано исключение ImproperlyConfigured
.
Расширенные возможности TransactionTestCase
¶
-
TransactionTestCase.
available_apps
¶ Предупреждение
Этот атрибут является частным API. В будущем он может быть изменен или удален без указания срока амортизации, например, для учета изменений в загрузке приложений.
Он используется для оптимизации собственного набора тестов Django, который содержит сотни моделей, но не имеет связей между моделями в разных приложениях.
По умолчанию
available_apps
устанавливается наNone
. После каждого теста Django вызываетflush
, чтобы сбросить состояние базы данных. Это опустошает все таблицы и выдает сигналpost_migrate
, который воссоздает один тип содержимого и четыре разрешения для каждой модели. Эта операция становится дорогой пропорционально количеству моделей.Установка
available_apps
в список приложений инструктирует Django вести себя так, как будто доступны только модели из этих приложений. ПоведениеTransactionTestCase
изменяется следующим образом:post_migrate
запускается перед каждым тестом для создания типов содержимого и разрешений для каждой модели в доступных приложениях, в случае их отсутствия.- После каждого теста Django очищает только таблицы, соответствующие моделям в доступных приложениях. Однако, на уровне базы данных, усечение может каскадировать на связанные модели в недоступных приложениях. Кроме того,
post_migrate
не срабатывает; он сработает после следующегоTransactionTestCase
, когда будет выбран правильный набор приложений.
Поскольку база данных не полностью очищена, если тест создает экземпляры моделей, не включенных в
available_apps
, они будут утекать и могут привести к неудаче несвязанных тестов. Будьте осторожны с тестами, использующими сессии; механизм сессий по умолчанию хранит их в базе данных.Поскольку
post_migrate
не выдается после очистки базы данных, его состояние послеTransactionTestCase
не такое же, как послеTestCase
: в нем отсутствуют строки, созданные слушателямиpost_migrate
. Учитывая order in which tests are executed, это не является проблемой, если либо всеTransactionTestCase
в данном тестовом наборе объявляютavailable_apps
, либо ни один из них.available_apps
является обязательным в собственном наборе тестов Django.
-
TransactionTestCase.
reset_sequences
¶ Установка
reset_sequences = True
наTransactionTestCase
будет гарантировать, что последовательности всегда сбрасываются перед выполнением теста:class TestsThatDependsOnPrimaryKeySequences(TransactionTestCase): reset_sequences = True def test_animal_pk(self): lion = Animal.objects.create(name="lion", sound="roar") # lion.pk is guaranteed to always be 1 self.assertEqual(lion.pk, 1)
Если вы явно не тестируете порядковые номера первичных ключей, рекомендуется не кодировать значения первичных ключей в тестах.
Использование
reset_sequences = True
замедлит выполнение теста, поскольку сброс первичного ключа является относительно дорогой операцией базы данных.
Обеспечение последовательного запуска тестовых классов¶
Если у вас есть тестовые классы, которые нельзя запускать параллельно (например, потому что они используют общий ресурс), вы можете использовать django.test.testcases.SerializeMixin
для их последовательного запуска. Этот миксин использует файловую систему lockfile
.
Например, вы можете использовать __file__
, чтобы определить, что все тестовые классы в том же файле, которые наследуются от SerializeMixin
, будут запускаться последовательно:
import os
from django.test import TestCase
from django.test.testcases import SerializeMixin
class ImageTestCaseMixin(SerializeMixin):
lockfile = __file__
def setUp(self):
self.filename = os.path.join(temp_storage_dir, 'my_file.png')
self.file = create_file(self.filename)
class RemoveImageTests(ImageTestCaseMixin, TestCase):
def test_remove_image(self):
os.remove(self.filename)
self.assertFalse(os.path.exists(self.filename))
class ResizeImageTests(ImageTestCaseMixin, TestCase):
def test_resize_image(self):
resize_image(self.file, (48, 48))
self.assertEqual(get_image_size(self.file), (48, 48))
Использование бегуна тестирования Django для тестирования многократно используемых приложений¶
Если вы пишете reusable application, вы, возможно, захотите использовать Django test runner, чтобы запустить свой собственный набор тестов и таким образом воспользоваться инфраструктурой тестирования Django.
Обычная практика - это каталог tests рядом с кодом приложения, со следующей структурой:
runtests.py
polls/
__init__.py
models.py
...
tests/
__init__.py
models.py
test_settings.py
tests.py
Давайте заглянем в несколько таких файлов:
#!/usr/bin/env python
import os
import sys
import django
from django.conf import settings
from django.test.utils import get_runner
if __name__ == "__main__":
os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.test_settings'
django.setup()
TestRunner = get_runner(settings)
test_runner = TestRunner()
failures = test_runner.run_tests(["tests"])
sys.exit(bool(failures))
Это сценарий, который вы вызываете для запуска набора тестов. Он устанавливает окружение Django, создает тестовую базу данных и запускает тесты.
Для ясности, этот пример содержит только необходимый минимум для использования бегуна тестирования Django. Возможно, вы захотите добавить опции командной строки для контроля многословности, передачи определенных тестовых меток для запуска и т.д.
SECRET_KEY = 'fake-key'
INSTALLED_APPS = [
"tests",
]
Этот файл содержит Django settings, необходимые для запуска тестов вашего приложения.
Опять же, это минимальный пример; для запуска ваших тестов могут потребоваться дополнительные настройки.
Поскольку пакет tests включается в INSTALLED_APPS
при запуске ваших тестов, вы можете определить модели только для тестов в его models.py
файле.
Использование различных фреймворков для тестирования¶
Очевидно, что unittest
- не единственный фреймворк тестирования Python. Хотя Django не предоставляет явной поддержки альтернативных фреймворков, он предоставляет возможность вызывать тесты, созданные для альтернативного фреймворка, как если бы это были обычные тесты Django.
Когда вы выполняете ./manage.py test
, Django смотрит на параметр TEST_RUNNER
, чтобы определить, что делать. По умолчанию TEST_RUNNER
указывает на 'django.test.runner.DiscoverRunner'
. Этот класс определяет поведение тестирования Django по умолчанию. Это поведение включает в себя:
- Выполнение глобальной предтестовой настройки.
- Ищет тесты в любом файле ниже текущего каталога, имя которого соответствует шаблону
test*.py
. - Создание тестовых баз данных.
- Запуск
migrate
для установки моделей и начальных данных в тестовые базы данных. - Выполнение system checks.
- Запуск найденных тестов.
- Уничтожение тестовых баз данных.
- Проведение глобального послетестового разбора.
Если вы определите свой собственный класс тестового бегуна и укажете TEST_RUNNER
на этот класс, Django будет выполнять ваш тестовый бегун всякий раз, когда вы запускаете ./manage.py test
. Таким образом, можно использовать любой тестовый фреймворк, который может быть выполнен из кода Python, или модифицировать процесс выполнения тестов Django, чтобы удовлетворить любые требования к тестированию, которые у вас могут быть.
Определение программы запуска тестов¶
Бегунок для тестирования - это класс, определяющий метод run_tests()
. Django поставляется с классом DiscoverRunner
, который определяет поведение тестирования Django по умолчанию. Этот класс определяет точку входа run_tests()
, а также ряд других методов, которые используются run_tests()
для установки, выполнения и разрушения набора тестов.
-
class
DiscoverRunner
(pattern='test*.py', top_level=None, verbosity=1, interactive=True, failfast=False, keepdb=False, reverse=False, debug_mode=False, debug_sql=False, parallel=0, tags=None, exclude_tags=None, test_name_patterns=None, pdb=False, buffer=False, enable_faulthandler=True, timing=True, shuffle=False, logger=None, **kwargs)[исходный код]¶ DiscoverRunner
будет искать тесты в любом файле, соответствующемpattern
.top_level
можно использовать для указания каталога, содержащего ваши модули Python верхнего уровня. Обычно Django определяет это автоматически, поэтому указывать этот параметр не обязательно. Если он указан, то, как правило, это должен быть каталог, содержащий ваш файлmanage.py
.verbosity
определяет количество уведомлений и отладочной информации, которая будет выводиться на консоль;0
- нет вывода,1
- нормальный вывод,2
- подробный вывод.Если
interactive
равноTrue
, тестовый пакет имеет разрешение запрашивать у пользователя инструкции при выполнении тестового пакета. Примером такого поведения может быть запрос разрешения на удаление существующей базы данных тестов. Еслиinteractive
равноFalse
, тестовый пакет должен иметь возможность запускаться без какого-либо ручного вмешательства.Если
failfast
равноTrue
, набор тестов прекратит выполнение после обнаружения первого сбоя теста.Если
keepdb
равноTrue
, тестовый пакет будет использовать существующую базу данных или создаст ее при необходимости. ЕслиFalse
, будет создана новая база данных, при этом пользователю будет предложено удалить существующую базу данных, если таковая имеется.Если
reverse
равноTrue
, тестовые случаи будут выполняться в обратном порядке. Это может быть полезно для отладки тестов, которые не изолированы должным образом и имеют побочные эффекты. Grouping by test class сохраняется при использовании этой опции. Эту опцию можно использовать вместе с--shuffle
, чтобы изменить порядок для определенного случайного семени.debug_mode
указывает, на что должна быть установлена настройкаDEBUG
перед запуском тестов.parallel
задает количество процессов. Еслиparallel
больше1
, то набор тестов будет выполняться вparallel
процессах. Если тестовых случаев меньше, чем настроенных процессов, Django соответственно уменьшит количество процессов. Каждый процесс получает свою собственную базу данных. Эта опция требует наличия стороннего пакетаtblib
для корректного отображения трассировок.tags
может использоваться для указания набора tags for filtering tests. Может комбинироваться сexclude_tags
.exclude_tags
может использоваться для указания набора tags for excluding tests. Может комбинироваться сtags
.Если
debug_sql
равноTrue
, то в случае неудачных тестов будут выведены SQL-запросы, записанные в журнал django.db.backends logger, а также обратная трассировка. Еслиverbosity
равно2
, то выводятся запросы во всех тестах.test_name_patterns
можно использовать для задания набора шаблонов для фильтрации тестовых методов и классов по их именам.Если
pdb
равноTrue
, отладчик (pdb
илиipdb
) будет порождаться при каждой ошибке или сбое теста.Если
buffer
равноTrue
, выводы из пройденных тестов будут отброшены.Если
enable_faulthandler
равноTrue
, тоfaulthandler
будет включен.Если
timing
имеет значениеTrue
, будет показано время выполнения теста, включая настройку базы данных и общее время работы.Если
shuffle
является целым числом, тестовые случаи будут перемешаны в случайном порядке перед выполнением, используя целое число в качестве случайной затравки. Еслиshuffle
равноNone
, семя будет генерироваться случайным образом. В обоих случаях семя будет зарегистрировано и установлено в значениеself.shuffle_seed
перед запуском тестов. Эта опция может использоваться для обнаружения тестов, которые не изолированы должным образом. Grouping by test class сохраняется при использовании этой опции.logger
можно использовать для передачи Python Logger object. Если передано, то логгер будет использоваться для регистрации сообщений вместо печати на консоль. Объект логгера будет соблюдать свой уровень протоколирования, а неverbosity
.Django может время от времени расширять возможности бегуна тестирования, добавляя новые аргументы. Объявление
**kwargs
позволяет это расширение. Если вы подклассDiscoverRunner
или пишете свой собственный бегунок тестирования, убедитесь, что он принимает**kwargs
.Ваша программа запуска тестов может также определять дополнительные параметры командной строки. Создайте или переопределите метод класса
add_arguments(cls, parser)
и добавьте пользовательские аргументы, вызвавparser.add_argument()
внутри метода, чтобы командаtest
могла использовать эти аргументы.New in Django 3.2:Добавлены аргументы
enable_faulthandler
иtiming
.New in Django 4.0:Добавлены аргументы
logger
иshuffle
.
Атрибуты¶
-
DiscoverRunner.
test_suite
¶ Класс, используемый для построения набора тестов. По умолчанию он имеет значение
unittest.TestSuite
. Его можно переопределить, если вы хотите реализовать другую логику для сбора тестов.
-
DiscoverRunner.
test_runner
¶ Это класс низкоуровневой программы запуска тестов, которая используется для выполнения отдельных тестов и форматирования результатов. По умолчанию он имеет значение
unittest.TextTestRunner
. Несмотря на досадное сходство в именовании, это не тот же тип класса, чтоDiscoverRunner
, который охватывает более широкий набор обязанностей. Вы можете переопределить этот атрибут, чтобы изменить способ выполнения тестов и создания отчетов.
-
DiscoverRunner.
test_loader
¶ Это класс, который загружает тесты, будь то из TestCases, модулей или иным образом, и собирает их в наборы тестов для выполнения бегуном. По умолчанию он установлен на
unittest.defaultTestLoader
. Вы можете переопределить этот атрибут, если ваши тесты будут загружаться необычным образом.
Методы¶
-
DiscoverRunner.
run_tests
(test_labels, **kwargs)[исходный код]¶ Запустите набор тестов.
test_labels
позволяет указать, какие тесты запускать, и поддерживает несколько форматов (см.DiscoverRunner.build_suite()
для списка поддерживаемых форматов).Не рекомендуется, начиная с версии 4.0:
extra_tests
- это список дополнительныхTestCase
экземпляров для добавления в набор, выполняемый программой запуска тестов. Эти дополнительные тесты выполняются в дополнение к тем, которые обнаружены в модулях, перечисленных вtest_labels
.Этот метод должен возвращать количество тестов, которые не прошли.
-
classmethod
DiscoverRunner.
add_arguments
(parser)[исходный код]¶ Переопределите этот метод класса, чтобы добавить пользовательские аргументы, принимаемые командой управления
test
. Подробности о добавлении аргументов в синтаксический анализатор см. вargparse.ArgumentParser.add_argument()
.
-
DiscoverRunner.
setup_test_environment
(**kwargs)[исходный код]¶ Устанавливает тестовую среду, вызывая
setup_test_environment()
и устанавливаяDEBUG
вself.debug_mode
(по умолчаниюFalse
).
-
DiscoverRunner.
build_suite
(test_labels=None, **kwargs)[исходный код]¶ Создает набор тестов, соответствующий предоставленным тестовым меткам.
test_labels
- это список строк, описывающих тесты, которые будут запущены. Метка теста может принимать одну из четырех форм:path.to.test_module.TestCase.test_method
– Запуск одного метода тестирования в тестовом примере.path.to.test_module.TestCase
– Запуск всех методов тестирования в тестовом примере.path.to.module
– Поиск и запуск всех тестов в названном пакете или модуле Python.path/to/directory
– Поиск и запуск всех тестов ниже именованной директории.
Если
test_labels
имеет значениеNone
, бегунок тестирования будет искать тесты во всех файлах ниже текущего каталога, имена которых совпадают с егоpattern
(см. выше).Не рекомендуется, начиная с версии 4.0:
extra_tests
- это список дополнительныхTestCase
экземпляров для добавления в набор, выполняемый программой запуска тестов. Эти дополнительные тесты выполняются в дополнение к тем, которые обнаружены в модулях, перечисленных вtest_labels
.Возвращает экземпляр
TestSuite
, готовый к выполнению.
-
DiscoverRunner.
setup_databases
(**kwargs)[исходный код]¶ Создает тестовые базы данных, вызывая
setup_databases()
.
-
DiscoverRunner.
run_checks
(databases)[исходный код]¶ Выполняет system checks на тестовом
databases
.
-
DiscoverRunner.
run_suite
(suite, **kwargs)[исходный код]¶ Запускает набор тестов.
Возвращает результат, полученный в результате выполнения набора тестов.
-
DiscoverRunner.
get_test_runner_kwargs
()[исходный код]¶ Возвращает аргументы ключевых слов для инстанцирования
DiscoverRunner.test_runner
.
-
DiscoverRunner.
teardown_databases
(old_config, **kwargs)[исходный код]¶ Уничтожает тестовые базы данных, восстанавливая предтестовые условия вызовом
teardown_databases()
.
-
DiscoverRunner.
teardown_test_environment
(**kwargs)[исходный код]¶ Восстанавливает среду предварительного тестирования.
-
DiscoverRunner.
suite_result
(suite, result, **kwargs)[исходный код]¶ Вычисляет и возвращает код возврата на основе набора тестов и результата этого набора тестов.
-
DiscoverRunner.
log
(msg, level=None)[исходный код]¶ - New in Django 4.0.
Если задано значение
logger
, записывает сообщение в журнал на заданное целое число logging level (например,logging.DEBUG
,logging.INFO
илиlogging.WARNING
). В противном случае сообщение выводится на консоль с соблюдением текущегоverbosity
. Например, сообщение не будет напечатано, еслиverbosity
равно 0,INFO
и выше будет напечатано, еслиverbosity
равно хотя бы 1, иDEBUG
будет напечатано, если оно равно хотя бы 2.level
по умолчанию равноlogging.INFO
.
Утилиты для тестирования¶
django.test.utils
¶
Чтобы помочь в создании собственной программы запуска тестов, Django предоставляет ряд полезных методов в модуле django.test.utils
.
-
setup_test_environment
(debug=None)[исходный код]¶ Выполняет глобальную настройку перед тестированием, например, устанавливает инструментарий для системы рендеринга шаблонов и настраивает макет почтового ящика.
Если
debug
не являетсяNone
, то параметрDEBUG
обновляется до его значения.
-
teardown_test_environment
()[исходный код]¶ Выполняет глобальное устранение последствий тестирования, например, удаление инструментария из системы шаблонов и восстановление нормальной работы почтовых служб.
-
setup_databases
(verbosity, interactive, *, time_keeper=None, keepdb=False, debug_sql=False, parallel=0, aliases=None, serialized_aliases=None, **kwargs)[исходный код]¶ Создает тестовые базы данных.
Возвращает структуру данных, содержащую достаточно подробную информацию, чтобы отменить внесенные изменения. Эти данные будут предоставлены функции
teardown_databases()
по завершении тестирования.Аргумент
aliases
определяет, для какихDATABASES
алиасов должны быть настроены тестовые базы данных. Если он не указан, то по умолчанию используются всеDATABASES
псевдонимы.Аргумент
serialized_aliases
определяет, какое подмножество тестовых баз данныхaliases
должно иметь сериализованное состояние для использования функции serialized_rollback. Если он не указан, то по умолчанию используется значениеaliases
.Changed in Django 3.2:Был добавлен глагол
time_keeper
, а все глаголы стали только ключевыми.Changed in Django 4.0:Был добавлен карг
serialized_aliases
.
-
teardown_databases
(old_config, parallel=0, keepdb=False)[исходный код]¶ Уничтожает тестовые базы данных, восстанавливая условия до тестирования.
old_config
- это структура данных, определяющая изменения в конфигурации базы данных, которые необходимо отменить. Это возвращаемое значение методаsetup_databases()
.
django.db.connection.creation
¶
Модуль создания бэкенда базы данных также предоставляет некоторые утилиты, которые могут быть полезны во время тестирования.
-
create_test_db
(verbosity=1, autoclobber=False, serialize=True, keepdb=False)¶ Создает новую тестовую базу данных и запускает
migrate
против нее.verbosity
имеет такое же поведение, как иrun_tests()
.autoclobber
описывает поведение, которое произойдет, если будет обнаружена база данных с тем же именем, что и тестовая база данных:- Если
autoclobber
равноFalse
, пользователю будет предложено одобрить уничтожение существующей базы данных. Если пользователь не одобрил, вызываетсяsys.exit
. - If
autoclobber
isTrue
, the database will be destroyed without consulting the user.
serialize
определяет, сериализует ли Django базу данных в JSON-строку в памяти перед запуском тестов (используется для восстановления состояния базы данных между тестами, если у вас нет транзакций). Вы можете установить значениеFalse
, чтобы ускорить время создания тестов, если у вас нет тестовых классов с serialized_rollback=True.Если вы используете стандартную программу запуска тестов, вы можете управлять этим с помощью записи
SERIALIZE
в словареTEST
.keepdb
определяет, следует ли при выполнении теста использовать существующую базу данных или создать новую. ЕслиTrue
, будет использована существующая база данных или создана, если ее нет. ЕслиFalse
, будет создана новая база данных, при этом пользователю будет предложено удалить существующую базу данных, если таковая имеется.Возвращает имя созданной тестовой базы данных.
create_test_db()
имеет побочный эффект изменения значенияNAME
вDATABASES
, чтобы оно соответствовало имени тестовой базы данных.- Если
-
destroy_test_db
(old_database_name, verbosity=1, keepdb=False)¶ Уничтожает базу данных, имя которой является значением
NAME
вDATABASES
, и устанавливаетNAME
в значениеold_database_name
.Аргумент
verbosity
имеет такое же поведение, как и дляDiscoverRunner
.Если аргумент
keepdb
равенTrue
, то соединение с базой данных будет закрыто, но база данных не будет уничтожена.
Интеграция с coverage.py
¶
Покрытие кода описывает, сколько исходного кода было протестировано. Оно показывает, какие части вашего кода проверяются тестами, а какие нет. Это важная часть тестирования приложений, поэтому настоятельно рекомендуется проверять покрытие ваших тестов.
Django можно легко интегрировать с coverage.py, инструментом для измерения покрытия кода программ на Python. Сначала install coverage.py. Далее, запустите из папки проекта, содержащей manage.py
:
coverage run --source='.' manage.py test myapp
Он запускает ваши тесты и собирает данные о покрытии выполняемых файлов в вашем проекте. Вы можете просмотреть отчет об этих данных, набрав следующую команду:
coverage report
Обратите внимание, что во время выполнения тестов был выполнен некоторый код Django, но он не указан здесь из-за флага source
, переданного предыдущей команде.
Для получения дополнительных возможностей, таких как аннотированные HTML-листинги с подробным описанием пропущенных строк, смотрите документацию coverage.py.