Расширенные темы тестирования

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

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

RequestFactory создает WSGI-подобные запросы. Если вы хотите создавать ASGI-подобные запросы, включая наличие корректного ASGI scope, вы можете вместо этого использовать django.test.AsyncRequestFactory.

Этот класс напрямую API-совместим с RequestFactory, с той лишь разницей, что он возвращает экземпляры ASGIRequest, а не WSGIRequest. Все его методы по-прежнему являются синхронными callables.

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

Для тестирования представлений на основе классов вне цикла запрос/ответ вы должны убедиться, что они настроены правильно, вызвав 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/', 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. Учитывая order in which tests are executed, это не является проблемой, если либо все 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 для тестирования многократно используемых приложений

Если вы пишете reusable application, вы, возможно, захотите использовать Django test runner, чтобы запустить свой собственный набор тестов и таким образом воспользоваться инфраструктурой тестирования 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 settings, необходимые для запуска тестов вашего приложения.

Опять же, это минимальный пример; для запуска ваших тестов могут потребоваться дополнительные настройки.

Поскольку пакет 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. Выполнение system checks.
  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, **kwargs)[исходный код]

DiscoverRunner будет искать тесты в любом файле, соответствующем pattern.

top_level можно использовать для указания каталога, содержащего ваши модули Python верхнего уровня. Обычно Django определяет это автоматически, поэтому указывать этот параметр не обязательно. Если он указан, то, как правило, это должен быть каталог, содержащий ваш файл manage.py.

verbosity определяет количество уведомлений и отладочной информации, которая будет выводиться на консоль; 0 - нет вывода, 1 - нормальный вывод, 2 - подробный вывод.

Если interactive равно True, тестовый пакет имеет разрешение запрашивать у пользователя инструкции при выполнении тестового пакета. Примером такого поведения может быть запрос разрешения на удаление существующей базы данных тестов. Если interactive равно False, тестовый пакет должен иметь возможность запускаться без какого-либо ручного вмешательства.

Если failfast равно True, набор тестов прекратит выполнение после обнаружения первого сбоя теста.

Если keepdb равно True, тестовый пакет будет использовать существующую базу данных или создаст ее при необходимости. Если False, будет создана новая база данных, при этом пользователю будет предложено удалить существующую базу данных, если таковая имеется.

Если reverse равно True, тестовые случаи будут выполняться в обратном порядке. Это может быть полезно для отладки тестов, которые не изолированы должным образом и имеют побочные эффекты. Grouping by test class сохраняется при использовании этой опции. Эту опцию можно использовать вместе с --shuffle, чтобы изменить порядок для определенного случайного семени.

debug_mode указывает, на что должна быть установлена настройка DEBUG перед запуском тестов.

parallel задает количество процессов. Если parallel больше 1, то набор тестов будет выполняться в parallel процессах. Если тестовых случаев меньше, чем настроенных процессов, Django соответственно уменьшит количество процессов. Каждый процесс получает свою собственную базу данных. Эта опция требует наличия стороннего пакета tblib для корректного отображения трассировок.

tags может использоваться для указания набора tags for filtering tests. Может комбинироваться с exclude_tags.

exclude_tags может использоваться для указания набора tags for excluding tests. Может комбинироваться с tags.

Если debug_sql равно True, то в случае неудачных тестов будут выведены SQL-запросы, записанные в журнал django.db.backends logger, а также обратная трассировка. Если verbosity равно 2, то выводятся запросы во всех тестах.

test_name_patterns можно использовать для задания набора шаблонов для фильтрации тестовых методов и классов по их именам.

Если pdb равно True, отладчик (pdb или ipdb) будет порождаться при каждой ошибке или сбое теста.

Если buffer равно True, выводы из пройденных тестов будут отброшены.

Если enable_faulthandler равно True, то faulthandler будет включен.

Если timing имеет значение True, будет показано время выполнения теста, включая настройку базы данных и общее время работы.

Если shuffle является целым числом, тестовые случаи будут перемешаны в случайном порядке перед выполнением, используя целое число в качестве случайной затравки. Если shuffle равно None, семя будет генерироваться случайным образом. В обоих случаях семя будет зарегистрировано и установлено в значение self.shuffle_seed перед запуском тестов. Эта опция может использоваться для обнаружения тестов, которые не изолированы должным образом. Grouping by test class сохраняется при использовании этой опции.

logger можно использовать для передачи Python Logger object. Если передано, то логгер будет использоваться для регистрации сообщений вместо печати на консоль. Объект логгера будет соблюдать свой уровень протоколирования, а не verbosity.

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

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

New in Django 3.2:

Добавлены аргументы enable_faulthandler и timing.

New in Django 4.0:

Добавлены аргументы logger и shuffle.

Атрибуты

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() для списка поддерживаемых форматов).

Не рекомендуется, начиная с версии 4.0: 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=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 (см. выше).

Не рекомендуется, начиная с версии 4.0: extra_tests - это список дополнительных TestCase экземпляров для добавления в набор, выполняемый программой запуска тестов. Эти дополнительные тесты выполняются в дополнение к тем, которые обнаружены в модулях, перечисленных в test_labels.

Возвращает экземпляр TestSuite, готовый к выполнению.

DiscoverRunner.setup_databases(**kwargs)[исходный код]

Создает тестовые базы данных, вызывая setup_databases().

DiscoverRunner.run_checks(databases)[исходный код]

Выполняет system 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)[исходный код]
New in Django 4.0.

Если задано значение logger, записывает сообщение в журнал на заданное целое число logging level (например, 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.

Changed in Django 3.2:

Был добавлен глагол time_keeper, а все глаголы стали только ключевыми.

Changed in Django 4.0:

Был добавлен карг serialized_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.
  • If autoclobber is True, the database will be destroyed without consulting the user.

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. Сначала install coverage.py. Далее, запустите из папки проекта, содержащей manage.py:

coverage run --source='.' manage.py test myapp

Он запускает ваши тесты и собирает данные о покрытии выполняемых файлов в вашем проекте. Вы можете просмотреть отчет об этих данных, набрав следующую команду:

coverage report

Обратите внимание, что во время выполнения тестов был выполнен некоторый код Django, но он не указан здесь из-за флага source, переданного предыдущей команде.

Для получения дополнительных возможностей, таких как аннотированные HTML-листинги с подробным описанием пропущенных строк, смотрите документацию coverage.py.

Вернуться на верх