Spec-Zone.ru › Django 5.0

Дополнительные темы тестирования

Фабрика запросов

class RequestFactory

Класс RequestFactory использует тот же API, что и клиент для тестирования. Однако вместо моделирования работы браузера, RequestFactory предоставляет способ создания экземпляра запроса, который может быть использован в качестве первого аргумента любого представления. Это означает, что вы можете тестировать функцию представления так же, как и любую другую функцию — как чёрный ящик, с точно известными входными данными, проверяя конкретные выходные данные.

API RequestFactory — это несколько ограниченный подмножество API клиента для тестирования:

  • Он имеет доступ только к HTTP-методам get(), post(), put(), delete(), head(), options() и trace().
  • Эти методы принимают все те же аргументы, кроме follow. Поскольку это всего лишь фабрика для создания запросов, обработка ответа возлагается на вас.
  • Он не поддерживает middleware. Атрибуты сессии и аутентификации должны быть предоставлены самим тестом, если они необходимы для правильной работы представления.
Изменено в Django 4.2:

Добавлен параметр headers.

Пример

Ниже приведен пример юнит-теста, использующего фабрику запросов:

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-объект.

Изменено в Django 4.2:

Добавлен параметр headers.

Тестирование представлений на основе классов

Для тестирования представлений на основе классов вне цикла запроса/ответа необходимо убедиться, что они настроены правильно, вызвав 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() , предварительно инициализировав представление, затем передав request в 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-адрес.

Тестирование и несколько баз данных

Тестирование конфигураций primary/replica

Если вы тестируете конфигурацию с несколькими базами данных с репликацией primary/replica (в некоторых базах данных это master/slave), эта стратегия создания тестовых баз данных вызывает проблемы. Когда создаются тестовые базы данных, репликация отсутствует, и в результате данные, созданные на primary, не будут видны на replica.

Для компенсации этого 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, или ни один из них.

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. Это поведение включает:

  1. Выполнение глобальной предварительной настройки тестов.
  2. Поиск тестов в любом файле ниже текущей директории, имя которого соответствует шаблону test*.py.
  3. Создание тестовых баз данных.
  4. Запуск migrate для установки моделей и начальных данных в тестовые базы данных.
  5. Запуск системных проверок.
  6. Запуск найденных тестов.
  7. Удаление тестовых баз данных.
  8. Выполнение глобального завершения после тестов.

Если вы определите собственный класс исполнителя тестов и укажете 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 объекта логгера. Если он предоставлен, логгер будет использоваться для записи сообщений вместо вывода в консоль. Объект логгера будет учитывать свой уровень логгирования вместо verbosity.

durations покажет список N самых медленных тестовых случаев. Установка этого параметра в значение 0 приведет к отображению продолжительности всех тестов. Требуется Python 3.12+.

Django может время от времени расширять возможности исполнителя тестов, добавляя новые аргументы. Объявление **kwargs позволяет это расширение. Если вы наследуете DiscoverRunner или создаёте свой собственный исполнитель тестов, убедитесь, что он принимает **kwargs.

Ваш исполнитель тестов может также определить дополнительные параметры командной строки. Создайте или переопределите метод класса add_arguments(cls, parser) и добавьте пользовательские аргументы, вызвав parser.add_argument() внутри метода, чтобы команда test могла использовать эти аргументы.

Добавлено в Django 5.0:

Параметр durations был добавлен.

Атрибуты

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.

END_OF_DOCUMENT_MARKER
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, 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.

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.

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. Далее, выполните следующее из папки вашего проекта, содержащей 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/5.0/topics/testing/advanced/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API