Дополнительные темы тестирования
Фабрика запросов
-
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
-
class AsyncRequestFactory[исходный код]
RequestFactory создаёт запросы, подобные WSGI-запросам. Чтобы создавать запросы, подобные ASGI-запросам, включая корректный ASGI scope, можно вместо этого использовать django.test.AsyncRequestFactory.
Этот класс полностью совместим по API с RequestFactory; единственное отличие в том, что он возвращает экземпляры ASGIRequest, а не экземпляры WSGIRequest. Все его методы по-прежнему являются синхронными вызываемыми объектами.
Произвольные именованные аргументы в defaults добавляются непосредственно в область видимости ASGI.
Тестирование представлений на основе классов
Чтобы тестировать представления на основе классов вне цикла запроса/ответа, необходимо убедиться, что они настроены корректно: для этого вызовите setup() после создания экземпляра.
Например, предположим, что имеется следующее представление на основе класса:
views.pyfrom 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() и после этого выполните код теста:
tests.pyfrom 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/",
headers={"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 — но потому, что это одна и та же база данных, а не потому, что между двумя базами данных реплицируются данные. Поскольку это зависит от транзакций, в тестах необходимо использовать TransactionTestCase, а не TestCase.
Управление порядком создания тестовых баз данных
По умолчанию 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. С учётом порядка выполнения тестов это не имеет значения, если либо всеTransactionTestCaseв наборе тестов объявляютavailable_apps, либо ни один из них этого не делает.В собственном наборе тестов Django использование
available_appsобязательно. - Перед каждым тестом отправляется сигнал
-
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 для тестирования повторно используемых приложений
Если вы пишете повторно используемое приложение, вы можете использовать средство запуска тестов Django для запуска собственного набора тестов и воспользоваться инфраструктурой тестирования Django.
Обычно рядом с кодом приложения создают каталог tests со следующей структурой:
runtests.py
polls/
__init__.py
models.py
...
tests/
__init__.py
models.py
test_settings.py
tests.py
Рассмотрим содержимое нескольких файлов:
runtests.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. При необходимости можно добавить параметры командной строки для управления подробностью вывода, передачи определённых меток тестов для запуска и т. д.
tests/test_settings.pySECRET_KEY = "fake-key"
INSTALLED_APPS = [
"tests",
]
Этот файл содержит настройки Django, необходимые для запуска тестов вашего приложения.
Это также минимальный пример; для запуска тестов могут потребоваться дополнительные настройки.
Поскольку при запуске тестов пакет 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для установки моделей и начальных данных в тестовые базы данных. - Запуск системных проверок.
- Запуск найденных тестов.
- Удаление тестовых баз данных.
- Выполнение общей заключительной очистки после тестов.
Если вы определите собственный класс запуска тестов и укажете его в настройке 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, durations=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, тестовые случаи будут выполняться в обратном порядке. Это может быть полезно для отладки тестов, которые недостаточно изолированы и имеют побочные эффекты. При использовании этого параметра сохраняется группировка по классу теста. Этот параметр можно использовать вместе с--shuffle, чтобы изменить порядок для определённого случайного начального значения.Параметр
debug_modeзадаёт значение настройкиDEBUGперед запуском тестов.Параметр
parallelзадаёт количество процессов. Еслиparallelбольше1, набор тестов будет выполняться вparallelпроцессах. Если классов тестовых случаев меньше, чем задано процессов, Django соответствующим образом уменьшит их количество. Каждый процесс использует собственную базу данных. Для корректного отображения трассировок этот параметр требует сторонний пакетtblib.Параметр
tagsможно использовать, чтобы указать набор тегов для фильтрации тестов. Его можно сочетать сexclude_tags.Параметр
exclude_tagsможно использовать, чтобы указать набор тегов для исключения тестов. Его можно сочетать сtags.Если
debug_sqlимеет значениеTrue, для неудачных тестовых случаев будут выводиться SQL-запросы, записанные в журнал django.db.backends, а также трассировка. Еслиverbosityимеет значение2, запросы будут выводиться для всех тестов.Параметр
test_name_patternsможно использовать, чтобы указать набор шаблонов для фильтрации тестовых методов и классов по их именам.Если
pdbимеет значениеTrue, при каждой ошибке или неудаче теста будет запускаться отладчик (pdbилиipdb).Если
bufferимеет значениеTrue, вывод успешно пройденных тестов будет отбрасываться.Если
enable_faulthandlerимеет значениеTrue, будет включёнfaulthandler.Если
timingимеет значениеTrue, будут показаны длительности выполнения тестов, включая настройку базы данных и общее время выполнения.Если
shuffle— целое число, перед выполнением тестовые случаи будут перемешаны в случайном порядке, а это число будет использовано в качестве начального значения генератора случайных чисел. Еслиshuffleимеет значениеNone, начальное значение будет сгенерировано случайным образом. В обоих случаях начальное значение будет записано в журнал и установлено вself.shuffle_seedперед запуском тестов. Этот параметр помогает обнаруживать недостаточно изолированные тесты. При его использовании сохраняется группировка по классу теста.Параметр
loggerможно использовать для передачи объекта Python Logger. Если он передан, для записи сообщений вместо вывода в консоль будет использоваться этот объект. Уровень журналирования объекта будет учитываться вместо параметраverbosity.Параметр
durationsвыводит список из N самых медленных тестовых случаев. Если установить для него значение0, будет показана длительность выполнения всех тестов.Время от времени Django может расширять возможности средства запуска тестов, добавляя новые аргументы. Объявление
**kwargsпозволяет выполнять такое расширение. Если вы создаёте подклассDiscoverRunnerили пишете собственное средство запуска тестов, убедитесь, что оно принимает**kwargs.Ваше средство запуска тестов также может определять дополнительные параметры командной строки. Создайте или переопределите метод класса
add_arguments(cls, parser)и добавьте пользовательские аргументы, вызвав внутри этого методаparser.add_argument(). Тогда командаtestсможет использовать эти аргументы.
Атрибуты
-
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()).Этот метод должен возвращать количество неудачных тестов.
-
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(см. выше).Возвращает экземпляр
TestSuite, готовый к запуску. -
-
DiscoverRunner.setup_databases(**kwargs)[исходный код] -
Создаёт тестовые базы данных, вызывая
setup_databases().
-
DiscoverRunner.run_checks(databases)[исходный код] -
Запускает системные проверки для тестового
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)[исходный код] -
Если задан
logger, записывает сообщение с указанным целочисленным уровнем журналирования (например,logging.DEBUG,logging.INFOилиlogging.WARNING). В противном случае сообщение выводится в консоль с учётом текущего значенияverbosity. Например, если значениеverbosityравно 0, сообщения не выводятся; при значенииverbosityне менее 1 выводятсяINFOи более высокие уровни; при значении не менее 2 выводитсяDEBUG. Значение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.
-
teardown_databases(old_config, parallel=0, keepdb=False)[исходный код] -
Удаляет тестовые базы данных и восстанавливает исходное состояние.
old_config— это структура данных, описывающая изменения конфигурации базы данных, которые необходимо отменить. Она является возвращаемым значением методаsetup_databases().
django.db.connection.creation
Модуль создания базы данных в серверной части также предоставляет вспомогательные средства, которые могут быть полезны при тестировании.
-
create_test_db(verbosity=1, autoclobber=False, keepdb=False) -
Создаёт новую тестовую базу данных и запускает для неё
migrate.Параметр
verbosityработает так же, как вrun_tests().Параметр
autoclobberопределяет, что произойдёт, если будет обнаружена база данных с тем же именем, что и у тестовой:- Если
autoclobberимеет значениеFalse, у пользователя будет запрошено разрешение на удаление существующей базы данных. Если пользователь не даст согласие, будет вызванsys.exit. - Если
autoclobberимеет значениеTrue, база данных будет удалена без запроса пользователя.
Параметр
keepdbопределяет, следует ли использовать существующую базу данных или создать новую. Если указаноTrue, будет использована существующая база данных или создана новая, если её нет. Если указаноFalse, будет создана новая база данных, а пользователю будет предложено удалить существующую, если она есть.Возвращает имя созданной тестовой базы данных.
Вызов
create_test_db()изменяет значениеNAMEвDATABASES, устанавливая имя тестовой базы данных.Устарело с версии 6.0: Именованный аргумент
serializeустарел. Передачаserialize=Trueавтоматически вызывалаserialize_db_to_string(), однако этот аргумент устарел, поскольку при сериализации могли выполняться запросы к нетестовым базам данных. - Если
-
destroy_test_db(old_database_name, verbosity=1, keepdb=False) -
Удаляет базу данных, имя которой задано значением
NAMEвDATABASES, и устанавливает дляNAMEзначениеold_database_name.Аргумент
verbosityработает так же, как вDiscoverRunner.Если аргумент
keepdbимеет значениеTrue, соединение с базой данных будет закрыто, но сама база данных не будет удалена.
-
serialize_db_to_string() -
Сериализует базу данных в строку JSON в памяти, которую можно использовать для восстановления состояния базы данных между тестами, если серверная часть не поддерживает транзакции или если в наборе тестов есть классы тестов с включённым параметром serialized_rollback=True.
Эту функцию следует вызывать только после создания всех тестовых баз данных, поскольку в зависимости от конфигурации маршрутизации в процессе сериализации могут выполняться запросы к нетестовым базам данных.
Интеграция с coverage.py
Покрытие кода показывает, какая часть исходного кода была проверена. Оно показывает, какие части кода выполняются тестами, а какие — нет. Это важная составляющая тестирования приложений, поэтому настоятельно рекомендуется проверять покрытие тестами.
Django легко интегрируется с coverage.py — инструментом для измерения покрытия кода программ Python. Сначала установите coverage. Затем из папки проекта, содержащей manage.py, выполните следующую команду:
coverage run --source='.' manage.py test myapp
Команда запускает тесты и собирает данные о покрытии для выполненных файлов проекта. Чтобы просмотреть отчёт по этим данным, выполните следующую команду:
coverage report
Обратите внимание: во время запуска тестов выполнялся некоторый код Django, но здесь он не перечислен из-за флага source, переданного предыдущей команде.
Дополнительные параметры, например аннотированные HTML-отчёты со строками, которые не были выполнены, описаны в документации coverage.py.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/topics/testing/advanced/