Расширенные темы тестирования¶
Фабрика запросов¶
- 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, вы можете вместо этого использовать django.test.AsyncRequestFactory.
Этот класс напрямую API-совместим с RequestFactory, с той лишь разницей, что он возвращает экземпляры ASGIRequest, а не экземпляры WSGIRequest. Все его методы по-прежнему являются синхронными вызываемыми объектами.
Аргументы произвольного ключевого слова в defaults добавляются непосредственно в область действия ASGI.
Тестирование представлений на основе классов¶
Чтобы протестировать представления на основе классов вне цикла запрос/ответ, вы должны убедиться, что они настроены правильно, вызвав setup() после создания экземпляра.
Например, предположив следующее представление на основе классов:
views.py¶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(), сначала создав экземпляр представления, затем передав запрос в setup(), прежде чем приступить к коду вашего теста:
tests.py¶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/",
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 создаст две независимые тестовые базы данных, это нарушит все тесты, ожидающие репликации. Однако база данных «реплика» была настроена как тестовое зеркало (с использованием тестовой настройки MIRROR <TEST_MIRROR>), что указывает на то, что во время тестирования «реплика» должна рассматриваться как зеркало «по умолчанию».
Когда тестовая среда настроена, тестовая версия реплики не создаётся. Вместо этого соединение с репликой будет перенаправлено на точку по умолчанию. В результате записи в default появятся в реплике, но потому, что на самом деле это одна и та же база данных, а не потому, что между двумя базами данных существует репликация данных. Поскольку это зависит от транзакций, тесты должны использовать TransactionTestCase вместо TestCase.
Управление порядком создания тестовых баз данных¶
По умолчанию Django предполагает, что все базы данных зависят от базы данных по умолчанию, и поэтому всегда сначала создает базу данных по умолчанию. Однако не предоставляется никаких гарантий относительно порядка создания любых других баз данных в вашей тестовой установке.
Если конфигурация вашей базы данных требует определенного порядка создания, вы можете указать существующие зависимости, используя настройку теста 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» будет создана первой, поскольку это единственный псевдоним базы данных без зависимостей. Следующими будут созданы псевдонимы «по умолчанию» и «трефы» (хотя порядок создания этой пары не гарантирован), затем «червы» и, наконец, «пики».
Если в определении 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-of-tests>`, это не проблема, при условии, что либо все 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 для тестирования повторно используемых приложений.¶
Если вы пишете приложение многократного использования, вы можете использовать средство запуска тестов 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.py¶SECRET_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.Создание тестовых баз данных.
Запуск миграции для установки моделей и исходных данных в тестовые базы данных.
Запуск системной проверки.
Запуск тестов, которые были найдены.
Уничтожение тестовых баз данных.
Выполнение глобального демонтажа после тестирования.
Если вы определите свой собственный класс запуска тестов и укажете 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 будет искать тесты в любом файле, соответствующем шаблону.
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, набор тестов будет выполняться впараллельныхпроцессах. Если классов тестовых примеров меньше, чем настроенных процессов, Django соответственно уменьшит количество процессов. Каждый процесс получает свою собственную базу данных. Для этого параметра требуется сторонний пакет tblib для правильного отображения обратных трассировок.tagsможно использовать для указания набора тегов для фильтрации тестов. Можно комбинировать с exclude_tags.exclude_tagsможно использовать для указания набора тегов для исключения тестов. Может комбинироваться с «тегами».Если
debug_sqlимеет значениеTrue, неудачные тестовые примеры будут выводить SQL-запросы, записанные в журнал django.db.backends <django-db-logger>`, а также обратную трассировку. Еслиverbosityравен2, то выводятся запросы во всех тестах.test_name_patternsможно использовать для указания набора шаблонов для фильтрации тестовых методов и классов по их именам.Если
pdbимеет значениеTrue, отладчик (pdbилиipdb) будет запускаться при каждой ошибке или сбое теста.Если
bufferимеет значениеTrue, результаты прохождения тестов будут отброшены.Если
enable_faulthandlerимеет значениеTrue,faulthandlerбудет включен.Если для параметра «time» установлено значение «True», будет показано время тестирования, включая настройку базы данных и общее время выполнения.
Если
shuffleявляется целым числом, перед выполнением тестовые случаи будут перетасованы в случайном порядке, используя целое число в качестве случайного начального числа. Если для параметра shuffle установлено значение None, начальное число будет генерироваться случайным образом. В обоих случаях начальное значение будет зарегистрировано и установлено в self.shuffle_seed перед запуском тестов. Эту опцию можно использовать для обнаружения тестов, которые не изолированы должным образом. Группировка по тестовому классу сохраняется при использовании этой опции.loggerможет использоваться для передачи Python-объекта <logger>`. Если это предусмотрено, средство ведения журнала будет использоваться для регистрации сообщений вместо вывода на консоль. Объект регистратора будет учитывать уровень протоколирования, а не «подробность».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.путь/к/каталогу— Найдите и запустите все тесты ниже указанного каталога.
Если
test_labelsимеет значениеNone, программа запуска тестов будет искать тесты во всех файлах ниже текущего каталога, имена которых соответствуют егошаблону(см. выше).Возвращает экземпляр TestSuite, готовый к запуску.
- DiscoverRunner.setup_databases(**kwargs)¶
Создает тестовые базы данных, вызывая
setup_databases().
- DiscoverRunner.run_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)¶
Если установлен
регистратор, регистрирует сообщение на заданном целочисленномуровне журнала`_ (например, ``logging.DEBUG,logging.INFOилиlogging.WARNING). В противном случае сообщение выводится на консоль с учетом текущей «детализации». Например, сообщение не будет напечатано, если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определяет, какое подмножество тестовых баз данныхпсевдонимовдолжно быть сериализовано, чтобы можно было использовать функцию serialized_rollback. Если он не указан, по умолчанию используетсяпсевдонимы.
- 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)¶
Создает новую тестовую базу данных и запускает для нее «миграцию».
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.