Расширенные темы тестирования
Фабрика запросов
-
class RequestFactory
Класс RequestFactory имеет тот же API, что и клиент тестирования. Однако вместо имитации поведения браузера, RequestFactory предоставляет способ создания экземпляра запроса, который можно использовать в качестве первого аргумента для любого представления. Это означает, что вы можете протестировать функцию представления так же, как любую другую функцию — как чёрную коробку с точно известными входными данными, проверяя определённые выходные данные.
API для RequestFactory — это немного ограниченный подмножество API клиента тестирования:
- Он имеет доступ только к HTTP-методам
get(),post(),put(),delete(),head(),options()иtrace(). - Эти методы принимают все те же аргументы, кроме
follow. Поскольку это всего лишь фабрика для создания запросов, вам нужно самостоятельно обработать ответ. - Он не поддерживает middleware. Атрибуты сессии и аутентификации должны быть предоставлены самим тестом, если они необходимы для правильной работы представления.
Пример
Ниже представлен пример unit-теста, использующего фабрику запросов:
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)
Тестирование представлений на основе классов
Для тестирования представлений на основе классов вне цикла запрос/ответ необходимо убедиться, что они настроены корректно, вызвав 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. Учитывая порядок выполнения тестов, это не проблема, при условии, что все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
Давайте посмотрим внутри нескольких из этих файлов:
#!/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, необходимые для запуска тестов вашего приложения.
Опять же, это минимальный пример; ваши тесты могут потребовать дополнительных настроек для запуска.
Поскольку пакет 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, test_name_patterns=None, pdb=False, **kwargs) -
DiscoverRunnerбудет искать тесты в любом файле, соответствующемpattern.top_levelможно использовать для указания каталога, содержащего ваши модули Python верхнего уровня. Обычно Django может определить это автоматически, поэтому нет необходимости указывать этот параметр. Если он указан, он обычно должен быть каталогом, содержащим ваш файлmanage.py.verbosityопределяет количество информационных и отладочных сообщений, которые будут выводиться в консоль;0— отсутствие вывода,1— нормальный вывод, а2— подробный вывод.Если
interactiveравноTrue, наборе тестов разрешено запрашивать у пользователя инструкции при выполнении набора тестов. Примером такого поведения является запрос разрешения на удаление существующей тестовой базы данных. ЕслиinteractiveравноFalse, набор тестов должен быть способен работать без ручного вмешательства.Если
failfastравноTrue, набор тестов прекратит работу после обнаружения первой ошибки теста.Если
keepdbравноTrue, набор тестов будет использовать существующую базу данных или создаст её при необходимости. ЕслиFalse, будет создана новая база данных, попросив пользователя удалить существующую, если она есть.Если
reverseравноTrue, тестовые случаи будут выполняться в обратном порядке. Это может быть полезно для отладки тестов, которые не изолированы должным образом и имеют побочные эффекты. Группировка по классам тестов сохраняется при использовании этого параметра.debug_modeопределяет, на какое значение следует установить настройкуDEBUGперед запуском тестов.Если
debug_sqlравноTrue, при ошибке тестовых случаев будут выводиться запросы SQL, записанные в журнал django.db.backends, а также трассировка. Еслиverbosityравно2, то запросы во всех тестах будут выводиться.test_name_patternsможет быть использован для указания набора шаблонов для фильтрации тестовых методов и классов по их именам.Если
pdbравноTrue, будет запущен отладчик (pdbилиipdb) при каждой ошибке или сбое теста.Django время от времени может расширять возможности набора тестов, добавляя новые аргументы. Объявление
**kwargsпозволяет это расширение. Если вы наследуете отDiscoverRunnerили пишете свой собственный набор тестов, убедитесь, что он принимает**kwargs.Ваш набор тестов также может определять дополнительные параметры командной строки. Создайте или переопределите метод класса
add_arguments(cls, parser)и добавьте настраиваемые аргументы, вызвавparser.add_argument()внутри метода, чтобы командаtestмогла использовать эти аргументы.Новое в Django 3.0:Добавлен аргумент
pdb.
Атрибуты
-
DiscoverRunner.test_suite -
Класс, используемый для построения набора тестов. По умолчанию он установлен в
unittest.TestSuite. Это можно переопределить, если вы хотите реализовать другую логику сбора тестов.
-
DiscoverRunner.test_runner -
Это класс низкоуровневого набора тестов, который используется для выполнения отдельных тестов и форматирования результатов. По умолчанию он установлен в
unittest.TextTestRunner. Несмотря на неудачное сходство в соглашениях об именовании, это не тот же тип класса, что иDiscoverRunner, который охватывает более широкий набор задач. Вы можете переопределить этот атрибут, чтобы изменить способ выполнения и отчётности тестов.
-
DiscoverRunner.test_loader -
Это класс, который загружает тесты, независимо от того, из TestCases, модулей или иного, и объединяет их в наборы тестов для выполнения набором тестов. По умолчанию он установлен в
unittest.defaultTestLoader. Вы можете переопределить этот атрибут, если ваши тесты будут загружаться необычным образом.
Методы
-
DiscoverRunner.run_tests(test_labels, extra_tests=None, **kwargs) -
Запустить набор тестов.
test_labelsпозволяет указать, какие тесты нужно запускать, и поддерживает несколько форматов (см.DiscoverRunner.build_suite()для списка поддерживаемых форматов).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, extra_tests=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(см. выше).extra_tests— список дополнительныхTestCaseэкземпляров, которые необходимо добавить в набор, выполняемый набором тестов. Эти дополнительные тесты выполняются в дополнение к тем, которые обнаружены в модулях, перечисленных вtest_labels.Возвращает экземпляр
TestSuiteготовый к выполнению. -
-
DiscoverRunner.setup_databases(**kwargs) -
Создает тестовые базы данных, вызывая
setup_databases().
-
DiscoverRunner.run_checks() -
Выполняет проверки системы.
-
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) -
Вычисляет и возвращает код возврата, основанный на наборе тестов и результате этого набора тестов.
Утилиты тестирования
django.test.utils
Для помощи в создании собственного набора тестов Django предоставляет ряд утилит в модуле django.test.utils.
-
setup_test_environment(debug=None) -
Выполняет глобальную настройку до выполнения тестов, например, установку инструментов для системы рендеринга шаблонов и настройку буфера фиктивных электронных писем.
Если
debugнеNone, настройкаDEBUGобновляется до её значения.
-
teardown_test_environment() -
Выполняет глобальную очистку после выполнения тестов, например, удаление инструментов из системы шаблонов и восстановление нормальной работы служб электронной почты.
-
setup_databases(verbosity, interactive, keepdb=False, debug_sql=False, parallel=0, aliases=None, **kwargs) -
Создает тестовые базы данных.
Возвращает структуру данных, которая предоставляет достаточно информации для отмены изменений, которые были внесены. Эти данные будут переданы функции
teardown_databases()по завершении тестирования.Аргумент
aliasesопределяет, для каких псевдонимовDATABASESдолжны быть настроены тестовые базы данных. Если его не указать, по умолчанию используются все псевдонимыDATABASES.Новое в Django 2.2:Добавлен аргумент
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будет вызвано, если пользователь не подтвердит. - Если autoclobber равно
True, база данных будет уничтожена без консультации с пользователем.
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-программ. Сначала установите coverage.py. Далее, выполните следующее из папки вашего проекта, содержащей 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/3.0/topics/testing/advanced/