Spec-Zone.ru › Django 6.0

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

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

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

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

Тестирование конфигураций «основная/реплика»

Если вы тестируете конфигурацию с несколькими базами данных, в которой настроена репликация «основная/реплика» (в некоторых базах данных её называют «ведущий/ведомый»), стратегия создания тестовых баз данных создаёт проблему. При создании тестовых баз данных репликации не будет, поэтому данные, созданные в основной базе, не появятся в реплике.

Чтобы решить эту проблему, 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.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 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/

Spec-Zone.ru

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