Spec-Zone.ru › Python 3.12

unittest — Модульное тестирование

Исходный код: Lib/unittest/__init__.py

(Если вы уже знакомы с основными понятиями тестирования, возможно, вы захотите перейти сразу к списку методов assert.)

Модульное тестирование с помощью unittest изначально было вдохновлено JUnit и имеет сходство с основными платформами модульного тестирования на других языках. Оно поддерживает автоматизацию тестирования, совместное использование кода настройки и завершения работы тестов, объединение тестов в коллекции и независимость тестов от платформы формирования отчётов.

Для этого unittest поддерживает несколько важных объектно-ориентированных понятий:

тестовая фикстура

Тестовая фикстура — это подготовка, необходимая для выполнения одного или нескольких тестов, а также связанные с ней действия по очистке. Например, она может включать создание временных или прокси-баз данных и каталогов либо запуск серверного процесса.

тестовый случай

Тестовый случай — это отдельная единица тестирования. Он проверяет определённый ответ на заданный набор входных данных. unittest предоставляет базовый класс TestCase, который можно использовать для создания новых тестовых случаев.

набор тестов

Набор тестов — это коллекция тестовых случаев, наборов тестов или того и другого. Он используется для объединения тестов, которые нужно выполнять вместе.

исполнитель тестов

Исполнитель тестов — это компонент, который управляет выполнением тестов и сообщает пользователю результат. Исполнитель может использовать графический или текстовый интерфейс либо возвращать специальное значение, обозначающее результаты выполнения тестов.

См. также

Module doctest

Другой модуль для поддержки тестирования, работающий совершенно иначе.

Простое тестирование в Smalltalk: использование шаблонов

Оригинальная статья Кента Бека о платформах тестирования, использующих шаблон, общий для unittest.

pytest

Сторонняя платформа модульного тестирования с более лёгким синтаксисом для написания тестов. Например, assert func(10) == 42.

Классификация средств тестирования Python

Обширный список средств тестирования Python, включая платформы функционального тестирования и библиотеки имитационных объектов.

Список рассылки Testing in Python

Группа по интересам для обсуждения тестирования и средств тестирования в Python.

Скрипт Tools/unittestgui/unittestgui.py из дистрибутива исходного кода Python — это графический инструмент для поиска и запуска тестов. Он предназначен главным образом для удобства тех, кто только начинает заниматься модульным тестированием. Для производственных сред рекомендуется запускать тесты с помощью системы непрерывной интеграции, например Buildbot, Jenkins, GitHub Actions или AppVeyor.

Простой пример

Модуль unittest предоставляет широкий набор инструментов для создания и запуска тестов. В этом разделе показано, что небольшого подмножества этих инструментов достаточно для удовлетворения потребностей большинства пользователей.

Ниже приведён короткий скрипт для проверки трёх строковых методов:

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

Тестовый случай создаётся путём создания подкласса unittest.TestCase. Три отдельных теста определены методами, имена которых начинаются с букв test. Это соглашение об именовании сообщает исполнителю тестов, какие методы являются тестами.

Суть каждого теста — вызов assertEqual() для проверки ожидаемого результата; assertTrue() или assertFalse() для проверки условия; либо assertRaises() для проверки того, что возникает определённое исключение. Эти методы используются вместо оператора assert, чтобы исполнитель тестов мог собрать результаты всех тестов и сформировать отчёт.

Методы setUp() и tearDown() позволяют определить инструкции, которые будут выполняться до и после каждого метода тестирования. Они подробнее рассматриваются в разделе Организация кода тестов.

В последнем блоке показан простой способ запуска тестов. unittest.main() предоставляет интерфейс командной строки для тестового скрипта. При запуске из командной строки приведённый выше скрипт выводит примерно следующее:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Если передать тестовому скрипту параметр -v, unittest.main() включит более подробный вывод и выведет следующее:

test_isupper (__main__.TestStringMethods.test_isupper) ... ok
test_split (__main__.TestStringMethods.test_split) ... ok
test_upper (__main__.TestStringMethods.test_upper) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

В приведённых выше примерах показаны наиболее часто используемые возможности unittest, которых достаточно для решения многих повседневных задач тестирования. В оставшейся части документации рассматривается весь набор возможностей с самого начала.

Изменено в версии 3.11: Использование возвращаемого значения метода тестирования (отличного от значения по умолчанию None) теперь устарело.

Интерфейс командной строки

Модуль unittest можно использовать из командной строки для запуска тестов из модулей, классов или даже отдельных методов тестирования:

python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

Можно передать список, содержащий любые сочетания имён модулей и полных имён классов или методов.

Тестовые модули также можно указать путём к файлу:

python -m unittest tests/test_something.py

Это позволяет использовать автодополнение имён файлов в оболочке при указании тестового модуля. Указанный файл всё равно должен импортироваться как модуль. Путь преобразуется в имя модуля: расширение «.py» удаляется, а разделители пути заменяются на «.». Если нужно выполнить тестовый файл, который нельзя импортировать как модуль, следует запустить файл напрямую.

Чтобы запустить тесты с более подробным выводом, передайте флаг -v:

python -m unittest -v test_module

При запуске без аргументов выполняется поиск тестов:

python -m unittest

Список всех параметров командной строки:

python -m unittest -h

Изменено в версии 3.2: В более ранних версиях можно было запускать только отдельные методы тестирования, но не модули или классы.

Параметры командной строки

unittest поддерживает следующие параметры командной строки:

-b, --buffer

Стандартные потоки вывода и ошибок буферизуются во время выполнения тестов. Вывод успешного теста отбрасывается. При сбое или ошибке теста вывод отображается как обычно и добавляется к сообщениям о сбоях.

-c, --catch

При нажатии Control-C во время выполнения тестов программа дожидается завершения текущего теста и выводит все результаты, полученные к этому моменту. Повторное нажатие Control-C вызывает обычное исключение KeyboardInterrupt.

См. раздел Обработка сигналов, где описаны функции, обеспечивающие эту возможность.

-f, --failfast

Остановить выполнение тестов при первой ошибке или сбое.

-k

Запускать только методы тестирования и классы, соответствующие шаблону или подстроке. Этот параметр можно указывать несколько раз; в таком случае включаются все тестовые случаи, соответствующие хотя бы одному из заданных шаблонов.

Шаблоны, содержащие подстановочный знак (*), сопоставляются с именем теста с помощью fnmatch.fnmatchcase(); в противном случае используется простое сопоставление с учётом регистра по подстроке.

Шаблоны сопоставляются с полным именем метода тестирования, импортированным загрузчиком тестов.

Например, -k foo соответствует foo_tests.SomeTest.test_something, bar_tests.SomeTest.test_foo, но не bar_tests.FooTest.test_something.

--locals

Показывать локальные переменные в трассировках стека.

--durations N

Показывать N самых медленных тестовых случаев (N=0 означает все).

Добавлено в версии 3.2: Добавлены параметры командной строки -b, -c и -f.

Добавлено в версии 3.5: Параметр командной строки --locals.

Добавлено в версии 3.7: Параметр командной строки -k.

Добавлено в версии 3.12: Параметр командной строки --durations.

Командную строку также можно использовать для поиска тестов, чтобы запускать все тесты проекта или только их часть.

Поиск тестов

Добавлено в версии 3.2.

Unittest поддерживает простой поиск тестов. Для совместимости с поиском тестов все тестовые файлы должны быть модулями или пакетами, импортируемыми из каталога верхнего уровня проекта (это означает, что их имена файлов должны быть допустимыми идентификаторами).

Поиск тестов реализован в TestLoader.discover(), но его также можно выполнять из командной строки. Основной способ использования из командной строки:

cd project_directory
python -m unittest discover

Примечание

Для краткости python -m unittest эквивалентно python -m unittest discover. Чтобы передать аргументы поиску тестов, необходимо явно использовать подкоманду discover.

Подкоманда discover принимает следующие параметры:

-v, --verbose

Подробный вывод

-s, --start-directory directory

Каталог, с которого начинается поиск (по умолчанию .)

-p, --pattern pattern

Шаблон для выбора тестовых файлов (по умолчанию test*.py)

-t, --top-level-directory directory

Каталог верхнего уровня проекта (по умолчанию совпадает с начальным каталогом)

Параметры -s, -p и -t можно передавать как позиционные аргументы в указанном порядке. Следующие две команды эквивалентны:

python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"

В качестве начального каталога можно указать не только путь, но и имя пакета, например myproject.subpackage.test. Указанное имя пакета будет импортировано, а его расположение в файловой системе будет использоваться как начальный каталог.

Внимание

Поиск тестов загружает тесты путём их импорта. Найдя все тестовые файлы в указанном начальном каталоге, поиск преобразует пути в имена пакетов для импорта. Например, foo/bar/baz.py будет импортирован как foo.bar.baz.

Если пакет установлен глобально и вы запускаете поиск тестов для другой его копии, импорт может произойти не из того места. В таком случае поиск тестов выдаст предупреждение и завершится.

Если указать начальный каталог как имя пакета, а не путь к каталогу, команда discover предполагает, что место, из которого выполнен импорт, и есть нужное вам место, поэтому предупреждение выведено не будет.

Тестовые модули и пакеты могут настраивать загрузку тестов и их поиск с помощью протокола load_tests.

Изменено в версии 3.4: Поиск тестов поддерживает пакеты пространств имён для начального каталога. Обратите внимание: необходимо также указать каталог верхнего уровня (например, python -m unittest discover -s root/namespace -t root).

Изменено в версии 3.11: В Python 3.11 из unittest удалена поддержка пакетов пространств имён. Она не работала начиная с Python 3.7. Начальный каталог и подкаталоги с тестами должны быть обычными пакетами, содержащими файл __init__.py.

Каталоги, содержащие начальный каталог, по-прежнему могут быть пакетами пространств имён. В этом случае необходимо указать начальный каталог как имя пакета с разделителями-точками, а целевой каталог — явно. Например:

# proj/  <-- current directory
#   namespace/
#     mypkg/
#       __init__.py
#       test_mypkg.py

python -m unittest discover -s namespace.mypkg -t .

Организация кода тестов

Основные строительные блоки модульного тестирования — это тестовые случаи, то есть отдельные сценарии, которые нужно настроить и проверить на корректность. В unittest тестовые случаи представлены экземплярами unittest.TestCase. Чтобы создать собственные тестовые случаи, необходимо написать подклассы TestCase или использовать FunctionTestCase.

Код тестирования экземпляра TestCase должен быть полностью автономным, чтобы его можно было запускать как изолированно, так и в произвольном сочетании с любым количеством других тестовых случаев.

В простейшем подклассе TestCase достаточно реализовать метод тестирования (то есть метод, имя которого начинается с test), содержащий код для выполнения конкретной проверки:

import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
    def test_default_widget_size(self):
        widget = Widget('The widget')
        self.assertEqual(widget.size(), (50, 50))

Обратите внимание: для проверки используется один из методов assert*, предоставляемых базовым классом TestCase. Если тест не пройдёт, будет вызвано исключение с поясняющим сообщением, и unittest определит тестовый случай как сбой. Все остальные исключения будут считаться ошибками.

Тестов может быть много, а их настройка может повторяться. К счастью, код настройки можно вынести в метод с именем setUp(), который платформа тестирования будет автоматически вызывать для каждого запускаемого теста:

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def test_default_widget_size(self):
        self.assertEqual(self.widget.size(), (50,50),
                         'incorrect default size')

    def test_widget_resize(self):
        self.widget.resize(100,150)
        self.assertEqual(self.widget.size(), (100,150),
                         'wrong size after resize')

Примечание

Порядок запуска различных тестов определяется сортировкой имён методов тестирования в соответствии со встроенным порядком сортировки строк.

Если во время выполнения теста метод setUp() вызовет исключение, платформа сочтёт, что тест завершился ошибкой, и метод тестирования выполнен не будет.

Аналогичным образом можно определить метод tearDown(), который выполнит очистку после запуска метода тестирования:

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def tearDown(self):
        self.widget.dispose()

Если setUp() завершился успешно, метод tearDown() будет выполнен независимо от того, успешно ли завершился метод тестирования.

Такая рабочая среда для кода тестирования называется тестовой фикстурой. Для выполнения каждого отдельного метода тестирования создаётся новый экземпляр TestCase, служащий уникальной тестовой фикстурой. Таким образом, setUp(), tearDown() и __init__() вызываются один раз для каждого теста.

Рекомендуется использовать реализации TestCase для группировки тестов по проверяемым возможностям. unittest предоставляет для этого механизм — набор тестов, представленный классом TestSuite из unittest. В большинстве случаев вызов unittest.main() выполнит нужные действия: соберёт все тестовые случаи модуля и запустит их.

Однако, если вы хотите настроить создание набора тестов, это можно сделать самостоятельно:

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('test_default_widget_size'))
    suite.addTest(WidgetTestCase('test_widget_resize'))
    return suite

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())

Определения тестовых случаев и наборов тестов можно разместить в тех же модулях, что и проверяемый код (например, widget.py), однако размещение кода тестов в отдельном модуле, например test_widget.py, имеет ряд преимуществ:

  • Тестовый модуль можно запускать отдельно из командной строки.
  • Код тестов проще отделить от поставляемого кода.
  • Становится меньше соблазна без веской причины изменять код тестов в соответствии с проверяемым кодом.
  • Код тестов должен меняться значительно реже, чем проверяемый им код.
  • Проверяемый код проще рефакторить.
  • Тесты для модулей, написанных на C, в любом случае должны находиться в отдельных модулях, так почему бы не придерживаться этого правила везде?
  • Если стратегия тестирования изменится, исходный код менять не потребуется.

Повторное использование старого кода тестов

Некоторые пользователи могут захотеть запускать имеющийся код тестов с помощью unittest, не преобразуя каждую старую тестовую функцию в подкласс TestCase.

Для этого unittest предоставляет класс FunctionTestCase. Этот подкласс TestCase можно использовать для обёртывания существующей тестовой функции. Также можно указать функции настройки и очистки.

Рассмотрим следующую тестовую функцию:

def testSomething():
    something = makeSomething()
    assert something.name is not None
    # ...

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

testcase = unittest.FunctionTestCase(testSomething,
                                     setUp=makeSomethingDB,
                                     tearDown=deleteSomethingDB)

Примечание

Хотя FunctionTestCase позволяет быстро перенести существующий набор тестов на систему, основанную на unittest, такой подход не рекомендуется. Если потратить время на создание корректных подклассов TestCase, в дальнейшем рефакторить тесты будет несравненно проще.

В некоторых случаях существующие тесты могли быть написаны с использованием модуля doctest. В таком случае doctest предоставляет класс DocTestSuite, который может автоматически создавать экземпляры unittest.TestSuite на основе существующих тестов, использующих doctest.

Пропуск тестов и ожидаемые сбои

Добавлено в версии 3.1.

Unittest позволяет пропускать отдельные методы тестирования и даже целые классы тестов. Кроме того, можно пометить тест как «ожидаемо завершающийся с ошибкой»: такой тест неисправен и завершится с ошибкой, но его не следует считать сбоем в TestResult.

Чтобы пропустить тест, достаточно воспользоваться декоратором skip() decorator или одним из его условных вариантов, вызвать TestCase.skipTest() в методе setUp() или методе тестирования либо непосредственно вызвать исключение SkipTest.

Простой пропуск теста выглядит так:

class MyTestCase(unittest.TestCase):

    @unittest.skip("demonstrating skipping")
    def test_nothing(self):
        self.fail("shouldn't happen")

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # windows specific testing code
        pass

    def test_maybe_skipped(self):
        if not external_resource_available():
            self.skipTest("external resource not available")
        # test code that depends on the external resource
        pass

В режиме подробного вывода пример выше выводит следующее:

test_format (__main__.MyTestCase.test_format) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase.test_nothing) ... skipped 'demonstrating skipping'
test_maybe_skipped (__main__.MyTestCase.test_maybe_skipped) ... skipped 'external resource not available'
test_windows_support (__main__.MyTestCase.test_windows_support) ... skipped 'requires Windows'

----------------------------------------------------------------------
Ran 4 tests in 0.005s

OK (skipped=4)

Пропускать можно и классы — точно так же, как методы:

@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
    def test_not_run(self):
        pass

Метод TestCase.setUp() также может пропустить тест. Это полезно, когда необходимый для настройки ресурс недоступен.

Для обозначения ожидаемых сбоев используется декоратор expectedFailure().

class ExpectedFailureTestCase(unittest.TestCase):
    @unittest.expectedFailure
    def test_fail(self):
        self.assertEqual(1, 0, "broken")

Нетрудно создать собственные декораторы для пропуска тестов: достаточно создать декоратор, который при необходимости вызывает для теста skip(). Этот декоратор пропускает тест, если у переданного объекта нет определённого атрибута:

def skipUnlessHasattr(obj, attr):
    if hasattr(obj, attr):
        return lambda func: func
    return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))

Следующие декораторы и исключение реализуют пропуск тестов и обработку ожидаемых сбоев:

@unittest.skip(reason)

Безусловно пропустить декорируемый тест. В reason следует указать причину пропуска теста.

@unittest.skipIf(condition, reason)

Пропустить декорируемый тест, если условие condition истинно.

@unittest.skipUnless(condition, reason)

Пропустить декорируемый тест, если условие condition ложно.

@unittest.expectedFailure

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

exception unittest.SkipTest(reason)

Это исключение вызывается для пропуска теста.

Обычно вместо его непосредственного вызова можно использовать TestCase.skipTest() или один из декораторов для пропуска тестов.

Для пропущенных тестов не будут выполняться методы setUp() и tearDown(). Для пропущенных классов не будут выполняться методы setUpClass() и tearDownClass(). Для пропущенных модулей не будут выполняться setUpModule() и tearDownModule().

Различение итераций теста с помощью подтестов

Добавлено в версии 3.4.

Если тесты различаются лишь незначительно, например некоторыми параметрами, unittest позволяет различать их внутри тела метода теста с помощью менеджера контекста subTest().

Например, следующий тест:

class NumbersTest(unittest.TestCase):

    def test_even(self):
        """
        Test that numbers between 0 and 5 are all even.
        """
        for i in range(0, 6):
            with self.subTest(i=i):
                self.assertEqual(i % 2, 0)

выведет следующее:

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=1)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=3)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=5)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

Без использования подтеста выполнение остановилось бы после первой ошибки, и диагностировать её было бы сложнее, поскольку значение i не отображалось бы:

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

Классы и функции

В этом разделе подробно описан API unittest.

Тестовые случаи

class unittest.TestCase(methodName='runTest')

Экземпляры класса TestCase представляют логические единицы тестирования в мире unittest. Этот класс предназначен для использования в качестве базового, а конкретные тесты реализуются в производных классах. Класс реализует интерфейс, необходимый средству запуска тестов для управления ими, а также методы, с помощью которых код тестов может проверять условия и сообщать о различных видах ошибок.

Каждый экземпляр TestCase выполняет один базовый метод — метод с именем methodName. В большинстве случаев использования TestCase вам не потребуется менять methodName или переопределять метод runTest() по умолчанию.

Изменено в версии 3.2: TestCase можно успешно создать, не указывая methodName. Это упрощает эксперименты с TestCase в интерактивном интерпретаторе.

Экземпляры TestCase предоставляют три группы методов: первая используется для запуска теста, вторая — реализацией теста для проверки условий и сообщения об ошибках, а третья содержит методы получения сведений о самом тесте.

Методы первой группы (для запуска теста):

setUp()

Метод, вызываемый для подготовки тестового окружения. Он вызывается непосредственно перед вызовом метода теста; любое исключение, кроме AssertionError или SkipTest, вызванное этим методом, считается ошибкой, а не провалом теста. Реализация по умолчанию ничего не делает.

tearDown()

Метод, вызываемый сразу после вызова метода теста и регистрации результата. Он вызывается даже в том случае, если метод теста вызвал исключение, поэтому при реализации в производных классах может потребоваться особенно тщательно проверять внутреннее состояние. Любое исключение, кроме AssertionError или SkipTest, вызванное этим методом, считается дополнительной ошибкой, а не провалом теста (тем самым увеличивая общее число зарегистрированных ошибок). Этот метод вызывается только в том случае, если setUp() завершается успешно, независимо от результата метода теста. Реализация по умолчанию ничего не делает.

setUpClass()

Метод класса, вызываемый перед запуском тестов отдельного класса. setUpClass вызывается с классом в качестве единственного аргумента и должен быть декорирован как classmethod():

@classmethod
def setUpClass(cls):
    ...

Подробнее см. в разделе Фикстуры классов и модулей.

Добавлено в версии 3.2.

tearDownClass()

Метод класса, вызываемый после выполнения тестов отдельного класса. tearDownClass вызывается с классом в качестве единственного аргумента и должен быть декорирован как classmethod():

@classmethod
def tearDownClass(cls):
    ...

Подробнее см. в разделе Фикстуры классов и модулей.

Добавлено в версии 3.2.

run(result=None)

Запускает тест, сохраняя результат в объекте TestResult, переданном в качестве result. Если result не указан или равен None, создаётся временный объект результата (вызовом метода defaultTestResult()), который затем используется. Объект результата возвращается вызывающему коду run().

Того же результата можно добиться, просто вызвав экземпляр TestCase.

Изменено в версии 3.3: Предыдущие версии run не возвращали результат. Вызов экземпляра также не возвращал его.

skipTest(reason)

Вызов этого метода во время выполнения метода теста или setUp() пропускает текущий тест. Дополнительные сведения см. в разделе Пропуск тестов и ожидаемые ошибки.

Добавлено в версии 3.1.

subTest(msg=None, **params)

Возвращает менеджер контекста, который выполняет вложенный блок кода как подтест. msg и params — необязательные произвольные значения, отображаемые при каждом провале подтеста, что позволяет чётко различать их.

Тестовый случай может содержать любое количество объявлений подтестов, которые могут быть вложены друг в друга на произвольную глубину.

Дополнительные сведения см. в разделе Различение итераций теста с помощью подтестов.

Добавлено в версии 3.4.

debug()

Запускает тест без сбора результата. Это позволяет передавать вызывающему коду исключения, возникшие в тесте, и может использоваться для поддержки запуска тестов в отладчике.

Класс TestCase предоставляет несколько методов утверждения для проверки условий и сообщения об ошибках. В следующей таблице перечислены наиболее часто используемые методы (другие методы утверждения см. в таблицах ниже):

Метод

Проверяет, что

Добавлен в версии

assertEqual(a, b)

a == b

assertNotEqual(a, b)

a != b

assertTrue(x)

bool(x) is True

assertFalse(x)

bool(x) is False

assertIs(a, b)

a is b

3.1

assertIsNot(a, b)

a is not b

3.1

assertIsNone(x)

x is None

3.1

assertIsNotNone(x)

x is not None

3.1

assertIn(a, b)

a in b

3.1

assertNotIn(a, b)

a not in b

3.1

assertIsInstance(a, b)

isinstance(a, b)

3.2

assertNotIsInstance(a, b)

not isinstance(a, b)

3.2

Все методы утверждения принимают аргумент msg, который при указании используется как сообщение об ошибке (см. также longMessage). Обратите внимание, что аргумент-ключевое слово msg можно передать методам assertRaises(), assertRaisesRegex(), assertWarns() и assertWarnsRegex() только при использовании их в качестве менеджеров контекста.

assertEqual(first, second, msg=None)

Проверяет, что first и second равны. Если значения не равны, тест завершается неудачей.

Кроме того, если first и second имеют совершенно одинаковый тип, который является одним из типов list, tuple, dict, set, frozenset или str, либо типом, для которого подкласс зарегистрировал функцию с помощью addTypeEqualityFunc(), будет вызвана функция сравнения равенства для конкретного типа, чтобы сформировать более информативное сообщение об ошибке по умолчанию (см. также список методов для конкретных типов).

Изменено в версии 3.1: Добавлен автоматический вызов функции сравнения равенства для конкретного типа.

Изменено в версии 3.2: assertMultiLineEqual() добавлен в качестве функции сравнения строк по умолчанию.

assertNotEqual(first, second, msg=None)

Проверяет, что first и second не равны. Если значения равны, тест завершается неудачей.

assertTrue(expr, msg=None)
assertFalse(expr, msg=None)

Проверяет, что expr истинно (или ложно).

Обратите внимание, что это эквивалентно bool(expr) is True, а не expr is True (для последнего используйте assertIs(expr, True)). Также следует избегать этого метода, если доступны более специализированные методы (например, assertEqual(a, b) вместо assertTrue(a == b)), поскольку при провале они предоставляют более информативное сообщение об ошибке.

assertIs(first, second, msg=None)
assertIsNot(first, second, msg=None)

Проверяет, что first и second являются (или не являются) одним и тем же объектом.

Добавлено в версии 3.1.

assertIsNone(expr, msg=None)
assertIsNotNone(expr, msg=None)

Проверяет, что expr равно (или не равно) None.

Добавлено в версии 3.1.

assertIn(member, container, msg=None)
assertNotIn(member, container, msg=None)

Проверяет, что member входит (или не входит) в container.

Добавлено в версии 3.1.

assertIsInstance(obj, cls, msg=None)
assertNotIsInstance(obj, cls, msg=None)

Проверяет, что obj является (или не является) экземпляром cls (который может быть классом или кортежем классов, как поддерживает isinstance()). Чтобы проверить точный тип, используйте assertIs(type(obj), cls).

Добавлено в версии 3.2.

Также можно проверять возникновение исключений, предупреждений и сообщений журнала с помощью следующих методов:

Метод

Проверяет, что

Добавлен в версии

assertRaises(exc, fun, *args, **kwds)

fun(*args, **kwds) вызывает исключение exc

assertRaisesRegex(exc, r, fun, *args, **kwds)

fun(*args, **kwds) вызывает исключение exc, а сообщение соответствует регулярному выражению r

3.1

assertWarns(warn, fun, *args, **kwds)

fun(*args, **kwds) вызывает предупреждение warn

3.2

assertWarnsRegex(warn, r, fun, *args, **kwds)

fun(*args, **kwds) вызывает предупреждение warn, а сообщение соответствует регулярному выражению r

3.2

assertLogs(logger, level)

В блоке with журналируются сообщения для logger с уровнем не ниже level

3.4

assertNoLogs(logger, level)

The with block does not log on

logger с уровнем не ниже level

3.10

assertRaises(exception, callable, *args, **kwds)
assertRaises(exception, *, msg=None)

Проверяет, что при вызове callable с любыми позиционными или именованными аргументами, также передаваемыми в assertRaises(), возникает исключение. Тест проходит, если возникает исключение exception; если возникает другое исключение, это считается ошибкой; если исключение не возникает, тест завершается неудачей. Чтобы перехватить любое исключение из группы, в качестве exception можно передать кортеж классов исключений.

Если указаны только аргументы exception и, возможно, msg, возвращается менеджер контекста, чтобы проверяемый код можно было записать непосредственно, а не оформлять как функцию:

with self.assertRaises(SomeException):
    do_something()

При использовании в качестве менеджера контекста assertRaises() принимает дополнительный аргумент-ключевое слово msg.

Менеджер контекста сохраняет перехваченный объект исключения в атрибуте exception. Это может быть полезно, если требуется выполнить дополнительные проверки возникшего исключения:

with self.assertRaises(SomeException) as cm:
    do_something()

the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)

Изменено в версии 3.1: Добавлена возможность использовать assertRaises() в качестве менеджера контекста.

Изменено в версии 3.2: Добавлен атрибут exception.

Изменено в версии 3.3: Добавлен аргумент-ключевое слово msg при использовании в качестве менеджера контекста.

assertRaisesRegex(exception, regex, callable, *args, **kwds)
assertRaisesRegex(exception, regex, *, msg=None)

Подобен assertRaises(), но также проверяет, что regex соответствует строковому представлению возникшего исключения. regex может быть объектом регулярного выражения или строкой с регулярным выражением, подходящим для использования в re.search(). Примеры:

self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$",
                       int, 'XYZ')

или:

with self.assertRaisesRegex(ValueError, 'literal'):
   int('XYZ')

Добавлено в версии 3.1: Добавлен под именем assertRaisesRegexp.

Изменено в версии 3.2: Переименован в assertRaisesRegex().

Изменено в версии 3.3: Добавлен аргумент-ключевое слово msg при использовании в качестве менеджера контекста.

assertWarns(warning, callable, *args, **kwds)
assertWarns(warning, *, msg=None)

Проверяет, что при вызове callable с любыми позиционными или именованными аргументами, также передаваемыми в assertWarns(), возникает предупреждение. Тест проходит, если возникает предупреждение warning, и завершается неудачей, если этого не происходит. Любое исключение считается ошибкой. Чтобы перехватить любое предупреждение из группы, в качестве warnings можно передать кортеж классов предупреждений.

Если указаны только аргументы warning и, возможно, msg, возвращается менеджер контекста, чтобы проверяемый код можно было записать непосредственно, а не оформлять как функцию:

with self.assertWarns(SomeWarning):
    do_something()

При использовании в качестве менеджера контекста assertWarns() принимает дополнительный аргумент-ключевое слово msg.

Менеджер контекста сохраняет перехваченный объект предупреждения в атрибуте warning, а исходную строку, вызвавшую предупреждение, — в атрибутах filename и lineno. Это может быть полезно, если требуется выполнить дополнительные проверки перехваченного предупреждения:

with self.assertWarns(SomeWarning) as cm:
    do_something()

self.assertIn('myfile.py', cm.filename)
self.assertEqual(320, cm.lineno)

Этот метод работает независимо от фильтров предупреждений, действующих в момент его вызова.

Добавлено в версии 3.2.

Изменено в версии 3.3: Добавлен аргумент-ключевое слово msg при использовании в качестве менеджера контекста.

assertWarnsRegex(warning, regex, callable, *args, **kwds)
assertWarnsRegex(warning, regex, *, msg=None)

Подобен assertWarns(), но также проверяет, что regex соответствует сообщению возникшего предупреждения. regex может быть объектом регулярного выражения или строкой с регулярным выражением, подходящим для использования в re.search(). Пример:

self.assertWarnsRegex(DeprecationWarning,
                      r'legacy_function\(\) is deprecated',
                      legacy_function, 'XYZ')

или:

with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):
    frobnicate('/etc/passwd')

Добавлено в версии 3.2.

Изменено в версии 3.3: Добавлен аргумент-ключевое слово msg при использовании в качестве менеджера контекста.

assertLogs(logger=None, level=None)

Менеджер контекста для проверки того, что в журнал logger или одного из его потомков записано хотя бы одно сообщение с уровнем не ниже заданного level.

Если указан, logger должен быть объектом logging.Logger или объектом str, содержащим имя регистратора. По умолчанию используется корневой регистратор, который перехватывает все сообщения, не заблокированные дочерним регистратором с отключённой передачей сообщений.

Если указан, level должен быть числовым уровнем журналирования или его строковым эквивалентом (например, "ERROR" или logging.ERROR). По умолчанию используется logging.INFO.

Тест проходит, если хотя бы одно сообщение, выведенное внутри блока with, соответствует условиям logger и level; в противном случае тест завершается неудачей.

Объект, возвращаемый менеджером контекста, — это вспомогательный объект для записи, который отслеживает соответствующие сообщения журнала. Он имеет два атрибута:

records

Список объектов logging.LogRecord, соответствующих сообщениям журнала.

output

Список объектов str с отформатированным выводом соответствующих сообщений.

Пример:

with self.assertLogs('foo', level='INFO') as cm:
    logging.getLogger('foo').info('first message')
    logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
                             'ERROR:foo.bar:second message'])

Добавлено в версии 3.4.

assertNoLogs(logger=None, level=None)

Менеджер контекста для проверки того, что в журнал logger или одного из его потомков не записываются сообщения с уровнем не ниже заданного level.

Если указан, logger должен быть объектом logging.Logger или объектом str, содержащим имя регистратора. По умолчанию используется корневой регистратор, который перехватывает все сообщения.

Если указан, level должен быть числовым уровнем журналирования или его строковым эквивалентом (например, "ERROR" или logging.ERROR). По умолчанию используется logging.INFO.

В отличие от assertLogs(), менеджер контекста ничего не возвращает.

Добавлено в версии 3.10.

Существуют и другие методы для выполнения более специализированных проверок, например:

Метод

Проверяет, что

Добавлен в

assertAlmostEqual(a, b)

round(a-b, 7) == 0

assertNotAlmostEqual(a, b)

round(a-b, 7) != 0

assertGreater(a, b)

a > b

3.1

assertGreaterEqual(a, b)

a >= b

3.1

assertLess(a, b)

a < b

3.1

assertLessEqual(a, b)

a <= b

3.1

assertRegex(s, r)

r.search(s)

3.1

assertNotRegex(s, r)

not r.search(s)

3.2

assertCountEqual(a, b)

a и b содержат одни и те же элементы в одинаковом количестве, независимо от их порядка.

3.2

assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)

Проверяет, равны ли first и second приблизительно (или не равны приблизительно), вычисляя разность, округляя её до заданного количества десятичных разрядов (по умолчанию 7) и сравнивая с нулём. Обратите внимание, что эти методы округляют значения до заданного количества десятичных разрядов (то есть, как функция round()), а не до значащих цифр.

Если вместо places указано значение delta, разность между first и second должна быть меньше или равна (либо больше) delta.

Одновременное указание delta и places вызывает исключение TypeError.

Изменено в версии 3.2: assertAlmostEqual() автоматически считает равные объекты приблизительно равными. assertNotAlmostEqual() автоматически завершается неудачей, если объекты равны. Добавлен именованный аргумент delta.

assertGreater(first, second, msg=None)
assertGreaterEqual(first, second, msg=None)
assertLess(first, second, msg=None)
assertLessEqual(first, second, msg=None)

Проверяет, что first соответственно больше (>), больше или равно (>=), меньше (<) или меньше или равно (<=) second — в зависимости от имени метода. В противном случае тест завершится неудачей:

>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"

Добавлено в версии 3.1.

assertRegex(text, regex, msg=None)
assertNotRegex(text, regex, msg=None)

Проверяет, соответствует ли поиск по regex тексту text (или не соответствует ему). В случае сбоя сообщение об ошибке будет содержать шаблон и text (либо шаблон и часть text, которой он неожиданно соответствовал). regex может быть объектом регулярного выражения или строкой с регулярным выражением, подходящим для использования с re.search().

Добавлено в версии 3.1: Добавлено под именем assertRegexpMatches.

Изменено в версии 3.2: Метод assertRegexpMatches() переименован в assertRegex().

Добавлено в версии 3.2: assertNotRegex().

assertCountEqual(first, second, msg=None)

Проверяет, что последовательность first содержит те же элементы, что и second, независимо от их порядка. Если это не так, будет сформировано сообщение об ошибке со списком различий между последовательностями.

Повторяющиеся элементы не игнорируются при сравнении first и second. Метод проверяет, что каждый элемент встречается в обеих последовательностях одинаковое количество раз. Эквивалентно: assertEqual(Counter(list(first)), Counter(list(second))), но работает также с последовательностями нехешируемых объектов.

Добавлено в версии 3.2.

Метод assertEqual() передаёт проверку равенства объектов одного типа различным методам, специфичным для типа. Эти методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощью addTypeEqualityFunc():

addTypeEqualityFunc(typeobj, function)

Регистрирует метод, специфичный для типа, который вызывается методом assertEqual() для проверки равенства двух объектов в точности одного и того же типа typeobj (не подклассов). function должна принимать два позиционных аргумента и третий именованный аргумент msg=None, как и assertEqual(). При обнаружении неравенства первых двух параметров она должна вызывать исключение self.failureException(msg), возможно, предоставляя полезную информацию и подробно объясняя различия в сообщении об ошибке.

Добавлено в версии 3.1.

Список методов, специфичных для типа, которые автоматически использует assertEqual(), приведён в следующей таблице. Обычно нет необходимости вызывать эти методы напрямую.

Метод

Используется для сравнения

Добавлен в

assertMultiLineEqual(a, b)

строк

3.1

assertSequenceEqual(a, b)

последовательностей

3.1

assertListEqual(a, b)

списков

3.1

assertTupleEqual(a, b)

кортежей

3.1

assertSetEqual(a, b)

множеств или неизменяемых множеств

3.1

assertDictEqual(a, b)

словарей

3.1

assertMultiLineEqual(first, second, msg=None)

Проверяет, что многострочная строка first равна строке second. Если строки не равны, в сообщение об ошибке будет включена разница между ними с выделением различий. Этот метод используется по умолчанию при сравнении строк с помощью assertEqual().

Добавлено в версии 3.1.

assertSequenceEqual(first, second, msg=None, seq_type=None)

Проверяет равенство двух последовательностей. Если указан seq_type, и first, и second должны быть экземплярами seq_type, иначе будет вызвана ошибка. Если последовательности различаются, формируется сообщение об ошибке, показывающее различия между ними.

Этот метод не вызывается напрямую методом assertEqual(), но используется для реализации методов assertListEqual() и assertTupleEqual().

Добавлено в версии 3.1.

assertListEqual(first, second, msg=None)
assertTupleEqual(first, second, msg=None)

Проверяет равенство двух списков или кортежей. Если они не равны, формируется сообщение об ошибке, показывающее только различия между ними. Ошибка также возникает, если один из параметров имеет неправильный тип. Эти методы используются по умолчанию при сравнении списков или кортежей с помощью assertEqual().

Добавлено в версии 3.1.

assertSetEqual(first, second, msg=None)

Проверяет равенство двух множеств. Если они не равны, формируется сообщение об ошибке со списком различий между множествами. Этот метод используется по умолчанию при сравнении множеств или неизменяемых множеств с помощью assertEqual().

Проверка завершается неудачей, если у first или second нет метода set.difference().

Добавлено в версии 3.1.

assertDictEqual(first, second, msg=None)

Проверяет равенство двух словарей. Если они не равны, формируется сообщение об ошибке, показывающее различия между словарями. Этот метод используется по умолчанию для сравнения словарей при вызовах assertEqual().

Добавлено в версии 3.1.

Наконец, TestCase предоставляет следующие методы и атрибуты:

fail(msg=None)

Безусловно сигнализирует о провале теста, используя msg или None в качестве сообщения об ошибке.

failureException

Этот атрибут класса задаёт исключение, вызываемое методом тестирования. Если тестовой среде требуется использовать специализированное исключение, возможно, чтобы передавать дополнительные сведения, необходимо унаследовать это исключение, чтобы обеспечить совместимость с тестовой средой. Начальное значение этого атрибута — AssertionError.

longMessage

Этот атрибут класса определяет, что происходит, когда пользовательское сообщение об ошибке передаётся в качестве аргумента msg вызову assertXYY, завершившемуся неудачей. Значение по умолчанию — True. В этом случае пользовательское сообщение добавляется в конец стандартного сообщения об ошибке. Если задано значение False, пользовательское сообщение заменяет стандартное.

Настройку класса можно переопределить для отдельных методов тестирования, присвоив атрибуту экземпляра self.longMessage значение True или False перед вызовом методов assert.

Настройка класса сбрасывается перед каждым вызовом теста.

Добавлено в версии 3.1.

maxDiff

Этот атрибут задаёт максимальную длину различий, выводимых методами assert, которые сообщают о различиях при сбое. По умолчанию она составляет 80*8 символов. Этот атрибут влияет на методы assert assertSequenceEqual() (включая все методы сравнения последовательностей, которые делегируют ему работу), assertDictEqual() и assertMultiLineEqual().

Установка для maxDiff значения None означает, что максимальная длина различий не ограничена.

Добавлено в версии 3.2.

Тестовые среды могут использовать следующие методы для сбора сведений о тесте:

countTestCases()

Возвращает количество тестов, представленных этим объектом теста. Для экземпляров TestCase результат всегда будет равен 1.

defaultTestResult()

Возвращает экземпляр класса результатов тестирования, который следует использовать для этого класса тестовых случаев (если методу run() не передан другой экземпляр результата).

Для экземпляров TestCase это всегда будет экземпляр TestResult; подклассам TestCase следует переопределять этот метод при необходимости.

id()

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

shortDescription()

Возвращает описание теста или None, если описание не задано. Реализация этого метода по умолчанию возвращает первую строку docstring метода тестирования, если она доступна, или None.

Изменено в версии 3.1: В версии 3.1 метод был изменён: имя теста стало добавляться в краткое описание даже при наличии docstring. Это вызвало проблемы совместимости с расширениями unittest, поэтому в Python 3.2 добавление имени теста перенесли в TextTestResult.

addCleanup(function, /, *args, **kwargs)

Добавляет функцию, которая будет вызвана после tearDown() для освобождения ресурсов, использованных во время теста. Функции вызываются в порядке, обратном порядку их добавления (LIFO). При вызове им передаются позиционные и именованные аргументы, указанные при добавлении в addCleanup().

Если setUp() завершается неудачей, то есть tearDown() не вызывается, все добавленные функции очистки всё равно будут вызваны.

Добавлено в версии 3.1.

enterContext(cm)

Входит в предоставленный менеджер контекста. В случае успеха также добавляет его метод __exit__() как функцию очистки с помощью addCleanup() и возвращает результат метода __enter__().

Добавлено в версии 3.11.

doCleanups()

Этот метод безусловно вызывается после tearDown() или после setUp(), если setUp() вызывает исключение.

Он отвечает за вызов всех функций очистки, добавленных с помощью addCleanup(). Если функции очистки нужно вызвать до tearDown(), можно вызвать doCleanups() самостоятельно.

doCleanups() извлекает методы из стека функций очистки по одному, поэтому его можно вызвать в любой момент.

Добавлено в версии 3.1.

classmethod addClassCleanup(function, /, *args, **kwargs)

Добавляет функцию, которая будет вызвана после tearDownClass() для освобождения ресурсов, использованных во время тестирования класса. Функции вызываются в порядке, обратном порядку их добавления (LIFO). При вызове им передаются позиционные и именованные аргументы, указанные при добавлении в addClassCleanup().

Если setUpClass() завершается неудачей, то есть tearDownClass() не вызывается, все добавленные функции очистки всё равно будут вызваны.

Добавлено в версии 3.8.

classmethod enterClassContext(cm)

Входит в предоставленный менеджер контекста. В случае успеха также добавляет его метод __exit__() как функцию очистки с помощью addClassCleanup() и возвращает результат метода __enter__().

Добавлено в версии 3.11.

classmethod doClassCleanups()

Этот метод безусловно вызывается после tearDownClass() или после setUpClass(), если setUpClass() вызывает исключение.

Он отвечает за вызов всех функций очистки, добавленных с помощью addClassCleanup(). Если функции очистки нужно вызвать до tearDownClass(), можно вызвать doClassCleanups() самостоятельно.

doClassCleanups() извлекает методы из стека функций очистки по одному, поэтому его можно вызвать в любой момент.

Добавлено в версии 3.8.

class unittest.IsolatedAsyncioTestCase(methodName='runTest')

Этот класс предоставляет API, аналогичный TestCase, и также принимает корутины в качестве функций тестирования.

Добавлено в версии 3.8.

async asyncSetUp()

Метод, вызываемый для подготовки тестового окружения. Вызывается после setUp(). Он вызывается непосредственно перед вызовом метода тестирования; любое исключение, вызванное этим методом, кроме AssertionError или SkipTest, будет считаться ошибкой, а не провалом теста. Реализация по умолчанию ничего не делает.

async asyncTearDown()

Метод, вызываемый сразу после вызова метода тестирования и регистрации результата. Вызывается перед tearDown(). Он вызывается даже в том случае, если метод тестирования вызвал исключение, поэтому реализации в подклассах должны особенно тщательно проверять внутреннее состояние. Любое исключение, вызванное этим методом, кроме AssertionError или SkipTest, будет считаться дополнительной ошибкой, а не провалом теста (что увеличит общее число зарегистрированных ошибок). Этот метод вызывается только в том случае, если asyncSetUp() завершился успешно, независимо от результата метода тестирования. Реализация по умолчанию ничего не делает.

addAsyncCleanup(function, /, *args, **kwargs)

Этот метод принимает корутину, которую можно использовать в качестве функции очистки.

async enterAsyncContext(cm)

Входит в предоставленный асинхронный менеджер контекста. В случае успеха также добавляет его метод __aexit__() как функцию очистки с помощью addAsyncCleanup() и возвращает результат метода __aenter__().

Добавлено в версии 3.11.

run(result=None)

Создаёт новый цикл событий для выполнения теста и собирает результат в объект TestResult, переданный в параметре result. Если result не указан или равен None, создаётся временный объект результата (путём вызова метода defaultTestResult()) и используется для выполнения теста. Объект результата возвращается вызывающему коду метода run(). По завершении теста все задачи в цикле событий отменяются.

Пример, иллюстрирующий порядок вызовов:

from unittest import IsolatedAsyncioTestCase

events = []


class Test(IsolatedAsyncioTestCase):


    def setUp(self):
        events.append("setUp")

    async def asyncSetUp(self):
        self._async_connection = await AsyncConnection()
        events.append("asyncSetUp")

    async def test_response(self):
        events.append("test_response")
        response = await self._async_connection.get("https://example.com")
        self.assertEqual(response.status_code, 200)
        self.addAsyncCleanup(self.on_cleanup)

    def tearDown(self):
        events.append("tearDown")

    async def asyncTearDown(self):
        await self._async_connection.close()
        events.append("asyncTearDown")

    async def on_cleanup(self):
        events.append("cleanup")

if __name__ == "__main__":
    unittest.main()

После выполнения теста events будет содержать ["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"].

class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)

Этот класс реализует часть интерфейса TestCase, которая позволяет средству запуска тестов выполнять тест, но не предоставляет методы, с помощью которых код теста может проверять и сообщать об ошибках. Этот класс используется для создания тестовых случаев на основе устаревшего кода тестов, что позволяет интегрировать его в тестовую среду на основе unittest.

Группировка тестов

class unittest.TestSuite(tests=())

Этот класс представляет собой объединение отдельных тестовых случаев и наборов тестов. Класс предоставляет интерфейс, необходимый средству запуска тестов, чтобы его можно было запускать так же, как любой другой тестовый случай. Запуск экземпляра TestSuite равносилен перебору набора с запуском каждого теста по отдельности.

Если задан параметр tests, он должен быть итерируемым объектом, содержащим отдельные тестовые случаи или другие наборы тестов, которые будут использованы для первоначального создания набора. Также предусмотрены дополнительные методы для последующего добавления тестовых случаев и наборов в коллекцию.

Объекты TestSuite во многом похожи на объекты TestCase, за исключением того, что они не реализуют тест непосредственно. Вместо этого они используются для объединения тестов в группы, которые следует запускать вместе. Для добавления тестов в экземпляры TestSuite доступны дополнительные методы:

addTest(test)

Добавить в набор объект TestCase или TestSuite.

addTests(tests)

Добавить в этот набор тестов все тесты из итерируемого объекта, содержащего экземпляры TestCase и TestSuite.

Это равносильно перебору tests с вызовом addTest() для каждого элемента.

Класс TestSuite имеет следующие общие методы с классом TestCase:

run(result)

Запустить тесты, связанные с этим набором, и сохранить результат в объекте результата тестирования, переданном в параметре result. Обратите внимание: в отличие от TestCase.run(), метод TestSuite.run() требует передачи объекта результата.

debug()

Запустить тесты, связанные с этим набором, не собирая результаты. Это позволяет передавать вызывающему коду исключения, возникающие в тестах, и может использоваться для поддержки запуска тестов в отладчике.

countTestCases()

Вернуть количество тестов, представленных этим объектом тестирования, включая все отдельные тесты и вложенные наборы.

__iter__()

Доступ к тестам, сгруппированным в TestSuite, всегда осуществляется посредством итерации. Подклассы могут лениво предоставлять тесты, переопределяя __iter__(). Обратите внимание: этот метод может вызываться несколько раз для одного набора (например, при подсчёте тестов или сравнении на равенство), поэтому тесты, возвращаемые при повторных итерациях до вызова TestSuite.run(), должны быть одинаковыми при каждом вызове итерации. После вызова TestSuite.run() вызывающим сторонам не следует полагаться на тесты, возвращаемые этим методом, если только вызывающая сторона не использует подкласс, переопределяющий TestSuite._removeTestAtIndex() для сохранения ссылок на тесты.

Изменено в версии 3.2: В более ранних версиях TestSuite обращался к тестам напрямую, а не посредством итерации, поэтому переопределения __iter__() было недостаточно для предоставления тестов.

Изменено в версии 3.4: В более ранних версиях TestSuite сохранял ссылки на каждый объект TestCase после вызова TestSuite.run(). Подклассы могут восстановить такое поведение, переопределив TestSuite._removeTestAtIndex().

При типичном использовании объекта TestSuite метод run() вызывается TestRunner, а не пользовательской тестовой средой.

Загрузка и запуск тестов

class unittest.TestLoader

Класс TestLoader используется для создания наборов тестов из классов и модулей. Обычно создавать экземпляр этого класса не нужно: модуль unittest предоставляет экземпляр, которым можно совместно пользоваться как unittest.defaultTestLoader. Однако использование подкласса или экземпляра позволяет настраивать некоторые параметры.

Объекты TestLoader имеют следующие атрибуты:

errors

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

Добавлено в версии 3.5.

Объекты TestLoader имеют следующие методы:

loadTestsFromTestCase(testCaseClass)

Возвращает набор всех тестовых случаев, содержащихся в testCaseClass, производном от TestCase.

Для каждого метода, имя которого указано в getTestCaseNames(), создаётся экземпляр тестового случая. По умолчанию это имена методов, начинающиеся с test. Если getTestCaseNames() не возвращает ни одного метода, но реализован метод runTest(), вместо этого для данного метода создаётся единственный тестовый случай.

loadTestsFromModule(module, *, pattern=None)

Возвращает набор всех тестовых случаев, содержащихся в указанном модуле. Этот метод ищет в module классы, производные от TestCase, и создаёт экземпляр класса для каждого определённого в нём тестового метода.

Примечание

Иерархия классов, производных от TestCase, может быть удобна для совместного использования фикстур и вспомогательных функций. Однако определение тестовых методов в базовых классах, которые не предназначены для непосредственного создания экземпляров, плохо сочетается с этим методом. Тем не менее такой подход может быть полезен, если фикстуры различаются и определяются в подклассах.

Если модуль предоставляет функцию load_tests, она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это и есть протокол load_tests. Аргумент pattern передаётся третьим аргументом в load_tests.

Изменено в версии 3.2: Добавлена поддержка load_tests.

Изменено в версии 3.5: Добавлена поддержка аргумента только по ключевому слову pattern.

Изменено в версии 3.12: Недокументированный и неофициальный параметр use_load_tests удалён.

loadTestsFromName(name, module=None)

Возвращает набор всех тестовых случаев, указанных строковым спецификатором.

Спецификатор name представляет собой «составное имя», которое может разрешаться в модуль, класс тестового случая, тестовый метод в классе тестового случая, экземпляр TestSuite или вызываемый объект, возвращающий экземпляр TestCase или TestSuite. Эти проверки выполняются в указанном здесь порядке; то есть метод потенциального класса тестового случая будет распознан как «тестовый метод в классе тестового случая», а не как «вызываемый объект».

Например, если у вас есть модуль SampleTests, содержащий производный от TestCase класс SampleTestCase с тремя тестовыми методами (test_one(), test_two() и test_three()), спецификатор 'SampleTests.SampleTestCase' заставит этот метод вернуть набор, который запустит все три тестовых метода. Спецификатор 'SampleTests.SampleTestCase.test_two' заставит его вернуть набор тестов, который запустит только тестовый метод test_two(). Спецификатор может ссылаться на модули и пакеты, которые ещё не были импортированы; они будут импортированы в качестве побочного эффекта.

Метод при необходимости разрешает name относительно заданного module.

Изменено в версии 3.5: Если при обходе name возникает ImportError или AttributeError, будет возвращён синтетический тест, который вызовет эту ошибку при запуске. Эти ошибки включаются в ошибки, накопленные в self.errors.

loadTestsFromNames(names, module=None)

Подобен loadTestsFromName(), но принимает последовательность имён, а не одно имя. Возвращаемое значение — набор тестов, включающий все тесты, определённые для каждого имени.

getTestCaseNames(testCaseClass)

Возвращает отсортированную последовательность имён методов, найденных в testCaseClass; это должен быть подкласс TestCase.

discover(start_dir, pattern='test*.py', top_level_dir=None)

Находит все тестовые модули, рекурсивно обходя подкаталоги указанного начального каталога, и возвращает объект TestSuite, содержащий их. Будут загружены только тестовые файлы, соответствующие pattern (используется сопоставление с шаблоном в стиле оболочки). Будут загружены только имена модулей, которые можно импортировать (то есть являющиеся допустимыми идентификаторами Python).

Все тестовые модули должны быть доступны для импорта из корневого каталога проекта. Если начальный каталог не является корневым каталогом, необходимо отдельно указать top_level_dir.

Если импорт модуля завершается неудачей, например из-за синтаксической ошибки, это будет зарегистрировано как одна ошибка, а обнаружение продолжится. Если сбой импорта вызван тем, что было вызвано исключение SkipTest, он будет зарегистрирован как пропуск, а не как ошибка.

Если найден пакет (каталог, содержащий файл с именем __init__.py), пакет будет проверен на наличие функции load_tests. Если такая функция есть, она будет вызвана package.load_tests(loader, tests, pattern). При обнаружении тестов гарантируется, что пакет будет проверен на наличие тестов только один раз за один вызов, даже если сама функция load_tests вызывает loader.discover.

Если существует load_tests, обнаружение не будет рекурсивно обходить пакет; load_tests отвечает за загрузку всех тестов в пакете.

Шаблон намеренно не сохраняется как атрибут загрузчика, чтобы пакеты могли самостоятельно продолжать обнаружение.

top_level_dir сохраняется во внутреннем состоянии и используется по умолчанию во вложенных вызовах discover(). То есть, если load_tests пакета вызывает loader.discover(), передавать этот аргумент не требуется.

start_dir может быть как составным именем модуля, так и каталогом.

Добавлено в версии 3.2.

Изменено в версии 3.4: Модули, при импорте которых вызывается SkipTest, регистрируются как пропущенные, а не как ошибочные.

Изменено в версии 3.4: start_dir может быть пакетом пространства имён.

Изменено в версии 3.4: Пути сортируются перед импортом, поэтому порядок выполнения остаётся одинаковым, даже если порядок файлов в базовой файловой системе не зависит от имён файлов.

Изменено в версии 3.5: Теперь найденные пакеты проверяются на наличие load_tests независимо от того, соответствует ли их путь шаблону pattern, поскольку имя пакета не может соответствовать шаблону по умолчанию.

Изменено в версии 3.11: start_dir не может быть пакетом пространства имён. Эта возможность не работала начиная с Python 3.7, а в Python 3.11 была официально удалена.

Изменено в версии 3.12.4: top_level_dir сохраняется только на время вызова discover.

Следующие атрибуты TestLoader можно настраивать с помощью создания подкласса или присваивания значения экземпляру:

testMethodPrefix

Строка, задающая префикс имён методов, которые будут считаться тестовыми методами. Значение по умолчанию — 'test'.

Это влияет на getTestCaseNames() и все методы loadTestsFrom*.

sortTestMethodsUsing

Функция, используемая для сравнения имён методов при их сортировке в getTestCaseNames() и всех методах loadTestsFrom*.

suiteClass

Вызываемый объект, создающий набор тестов из списка тестов. Методы созданного объекта не требуются. Значение по умолчанию — класс TestSuite.

Это влияет на все методы loadTestsFrom*.

testNamePatterns

Список шаблонов имён тестов с подстановочными знаками в стиле оболочки Unix, которым должны соответствовать тестовые методы, чтобы попасть в наборы тестов (см. параметр -k).

Если этому атрибуту присвоено значение, отличное от None (значение по умолчанию), все тестовые методы, включаемые в наборы тестов, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что сопоставление всегда выполняется с помощью fnmatch.fnmatchcase(), поэтому, в отличие от шаблонов, передаваемых параметру -k, простые шаблоны подстрок необходимо преобразовать с помощью подстановочных знаков *.

Это влияет на все методы loadTestsFrom*.

Добавлено в версии 3.7.

class unittest.TestResult

Этот класс используется для сбора сведений о том, какие тесты завершились успешно, а какие — неудачно.

Объект TestResult хранит результаты набора тестов. Классы TestCase и TestSuite обеспечивают правильную запись результатов; авторам тестов не нужно беспокоиться о регистрации исходов тестов.

Средствам тестирования, созданным на основе unittest, может потребоваться доступ к объекту TestResult, созданному при запуске набора тестов, для подготовки отчётов; для этой цели экземпляр TestResult возвращается методом TestRunner.run().

Экземпляры TestResult имеют следующие атрибуты, полезные при изучении результатов запуска набора тестов:

errors

Список, содержащий 2-кортежи из экземпляров TestCase и строк с отформатированными трассировками стека. Каждый кортеж представляет тест, вызвавший неожиданное исключение.

failures

Список, содержащий 2-кортежи из экземпляров TestCase и строк с отформатированными трассировками стека. Каждый кортеж представляет тест, в котором сбой был явно зафиксирован с помощью методов assert*.

skipped

Список, содержащий 2-кортежи из экземпляров TestCase и строк с указанием причины пропуска теста.

Добавлено в версии 3.1.

expectedFailures

Список, содержащий 2-кортежи из экземпляров TestCase и строк с отформатированными трассировками стека. Каждый кортеж представляет ожидаемый сбой или ошибку тестового случая.

unexpectedSuccesses

Список, содержащий экземпляры TestCase, помеченные как ожидаемые сбои, но завершившиеся успешно.

collectedDurations

Список, содержащий 2-кортежи с именами тестовых случаев и числами с плавающей точкой, представляющими время выполнения каждого запущенного теста.

Добавлено в версии 3.12.

shouldStop

Устанавливается в True, когда выполнение тестов следует остановить с помощью stop().

testsRun

Общее количество тестов, запущенных к этому моменту.

buffer

Если установлено значение true, вывод sys.stdout и sys.stderr будет буферизоваться между вызовами startTest() и stopTest(). Собранный вывод будет передан в реальные sys.stdout и sys.stderr только в случае сбоя или ошибки теста. Любой вывод также добавляется к сообщению о сбое или ошибке.

Добавлено в версии 3.2.

failfast

Если установлено значение true, при первом сбое или ошибке будет вызван stop(), и выполнение тестов прекратится.

Добавлено в версии 3.2.

tb_locals

Если установлено значение true, в трассировках стека будут отображаться локальные переменные.

Добавлено в версии 3.5.

wasSuccessful()

Возвращает True, если все запущенные к этому моменту тесты завершились успешно; в противном случае возвращает False.

Изменено в версии 3.4: Возвращает False, если среди тестов, помеченных декоратором expectedFailure(), были какие-либо unexpectedSuccesses.

stop()

Этот метод можно вызвать, чтобы сообщить о необходимости прервать выполняемый набор тестов, установив атрибут shouldStop в True. Объекты TestRunner должны учитывать этот флаг и возвращаться, не запуская дополнительные тесты.

Например, класс TextTestRunner использует эту возможность, чтобы остановить средство тестирования, когда пользователь подаёт сигнал прерывания с клавиатуры. Интерактивные инструменты, предоставляющие реализации TestRunner, могут использовать её аналогичным образом.

Следующие методы класса TestResult используются для поддержки внутренних структур данных и могут быть переопределены в подклассах для реализации дополнительных требований к отчётности. Это особенно полезно при создании инструментов, поддерживающих интерактивную отчётность во время выполнения тестов.

startTest(test)

Вызывается непосредственно перед запуском тестового случая test.

stopTest(test)

Вызывается после выполнения тестового случая test, независимо от результата.

startTestRun()

Вызывается один раз перед выполнением любых тестов.

Добавлено в версии 3.1.

stopTestRun()

Вызывается один раз после выполнения всех тестов.

Добавлено в версии 3.1.

addError(test, err)

Вызывается, когда тестовый случай test вызывает неожиданное исключение. err — кортеж в формате, возвращаемом sys.exc_info(): (type, value, traceback).

Реализация по умолчанию добавляет кортеж (test, formatted_err) к атрибуту экземпляра errors, где formatted_err — отформатированная трассировка стека, полученная из err.

addFailure(test, err)

Вызывается, когда тестовый случай test сообщает о сбое. err — кортеж в формате, возвращаемом sys.exc_info(): (type, value, traceback).

Реализация по умолчанию добавляет кортеж (test, formatted_err) к атрибуту экземпляра failures, где formatted_err — отформатированная трассировка стека, полученная из err.

addSuccess(test)

Вызывается, когда тестовый случай test завершается успешно.

Реализация по умолчанию ничего не делает.

addSkip(test, reason)

Вызывается, когда тестовый случай test пропускается. reason — указанная тестом причина пропуска.

Реализация по умолчанию добавляет кортеж (test, reason) к атрибуту экземпляра skipped.

addExpectedFailure(test, err)

Вызывается, когда тестовый случай test завершается сбоем или ошибкой, но помечен декоратором expectedFailure().

Реализация по умолчанию добавляет кортеж (test, formatted_err) к атрибуту экземпляра expectedFailures, где formatted_err — отформатированная трассировка стека, полученная из err.

addUnexpectedSuccess(test)

Вызывается, когда тестовый случай test помечен декоратором expectedFailure(), но завершается успешно.

Реализация по умолчанию добавляет тест к атрибуту экземпляра unexpectedSuccesses.

addSubTest(test, subtest, outcome)

Вызывается по завершении подтеста. test — тестовый случай, соответствующий тестовому методу. subtest — пользовательский экземпляр TestCase, описывающий подтест.

Если outcome равен None, подтест завершился успешно. В противном случае он завершился неудачно с исключением, где outcome — кортеж в формате, возвращаемом sys.exc_info(): (type, value, traceback).

Реализация по умолчанию ничего не делает в случае успеха и регистрирует сбои подтестов как обычные сбои.

Добавлено в версии 3.4.

addDuration(test, elapsed)

Вызывается по завершении тестового случая. elapsed — время в секундах, включающее выполнение функций очистки.

Добавлено в версии 3.12.

class unittest.TextTestResult(stream, descriptions, verbosity, *, durations=None)

Конкретная реализация TestResult, используемая классом TextTestRunner. Для обеспечения совместимости при изменении интерфейса подклассы должны принимать **kwargs.

Добавлено в версии 3.2.

Изменено в версии 3.12: Добавлен именованный параметр durations.

unittest.defaultTestLoader

Экземпляр класса TestLoader, предназначенный для совместного использования. Если настраивать TestLoader не требуется, этот экземпляр можно использовать вместо многократного создания новых экземпляров.

class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False, durations=None)

Базовая реализация средства запуска тестов, выводящая результаты в поток. Если stream — None (значение по умолчанию), в качестве выходного потока используется sys.stderr. Этот класс имеет несколько настраиваемых параметров, но в целом очень прост. Графические приложения, запускающие наборы тестов, должны предоставлять альтернативные реализации. Такие реализации должны принимать **kwargs, поскольку интерфейс для создания средств запуска меняется при добавлении возможностей в unittest.

По умолчанию это средство запуска показывает DeprecationWarning, PendingDeprecationWarning, ResourceWarning и ImportWarning, даже если они по умолчанию игнорируются. Это поведение можно переопределить с помощью параметров Python -Wd или -Wa (см. Управление предупреждениями), оставив warnings равным None.

Изменено в версии 3.2: Добавлен параметр warnings.

Изменено в версии 3.2: Поток по умолчанию устанавливается в sys.stderr во время создания экземпляра, а не во время импорта.

Изменено в версии 3.5: Добавлен параметр tb_locals.

Изменено в версии 3.12: Добавлен параметр durations.

_makeResult()

Этот метод возвращает экземпляр TestResult, используемый методом run(). Он не предназначен для прямого вызова, но может быть переопределён в подклассах для предоставления пользовательского TestResult.

_makeResult() создаёт экземпляр класса или вызываемого объекта, переданного в конструктор TextTestRunner в качестве аргумента resultclass. Если resultclass не указан, используется значение по умолчанию TextTestResult. Класс результата создаётся со следующими аргументами:

stream, descriptions, verbosity
run(test)

Этот метод является основным публичным интерфейсом TextTestRunner. В качестве аргумента он принимает экземпляр TestSuite или TestCase. Объект TestResult создаётся вызовом _makeResult(), затем выполняются тесты и результаты выводятся в stdout.

unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None)

Программа командной строки, которая загружает набор тестов из module и запускает их; прежде всего она предназначена для удобного запуска модулей тестов. Простейший способ использования этой функции — добавить следующую строку в конец скрипта с тестами:

if __name__ == '__main__':
    unittest.main()

Чтобы запускать тесты с более подробной информацией, передайте аргумент verbosity:

if __name__ == '__main__':
    unittest.main(verbosity=2)

Аргумент defaultTest — это имя одного теста или итерируемый объект с именами тестов, которые нужно запустить, если через argv не указаны имена тестов. Если он не указан или равен None и через argv не переданы имена тестов, запускаются все тесты, найденные в module.

Аргумент argv может быть списком параметров, переданных программе; первым элементом должно быть имя программы. Если он не указан или равен None, используются значения sys.argv.

Аргумент testRunner может быть классом средства запуска тестов или уже созданным его экземпляром. По умолчанию main вызывает sys.exit() с кодом завершения, указывающим на успех (0) или неудачу (1) запущенных тестов. Код завершения 5 означает, что ни один тест не был запущен или пропущен.

Аргумент testLoader должен быть экземпляром TestLoader; по умолчанию используется defaultTestLoader.

main можно использовать в интерактивном интерпретаторе, передав аргумент exit=False. В этом случае результат выводится в стандартный поток вывода, а вызов sys.exit() не выполняется:

>>> from unittest import main
>>> main(module='test_module', exit=False)

Параметры failfast, catchbreak и buffer действуют так же, как одноимённые параметры командной строки.

Аргумент warnings задаёт фильтр предупреждений, используемый при запуске тестов. Если он не указан, будет сохранено значение None, если программе python передан параметр -W (см. Управление предупреждениями); в противном случае ему будет присвоено значение 'default'.

Вызов main возвращает объект с атрибутом result, содержащим результат выполненных тестов в виде объекта unittest.TestResult.

Изменено в версии 3.1: Добавлен параметр exit.

Изменено в версии 3.2: Добавлены параметры verbosity, failfast, catchbreak, buffer и warnings.

Изменено в версии 3.4: Параметр defaultTest теперь также принимает итерируемый объект с именами тестов.

Протокол load_tests

Добавлено в версии 3.2.

Модули или пакеты могут настраивать способ загрузки тестов из них при обычном запуске тестов или поиске тестов, реализовав функцию с именем load_tests.

Если модуль тестов определяет load_tests, функция будет вызвана методом TestLoader.loadTestsFromModule() со следующими аргументами:

load_tests(loader, standard_tests, pattern)

где pattern передаётся непосредственно из loadTestsFromModule. По умолчанию используется None.

Функция должна возвращать TestSuite.

loader — экземпляр TestLoader, выполняющий загрузку. standard_tests — тесты, которые по умолчанию загружались бы из модуля. Обычно модули тестов хотят лишь добавить тесты в стандартный набор или удалить их из него. Третий аргумент используется при загрузке пакетов в процессе поиска тестов.

Типичная функция load_tests, загружающая тесты из определённого набора классов TestCase, может выглядеть так:

test_cases = (TestCase1, TestCase2, TestCase3)

def load_tests(loader, tests, pattern):
    suite = TestSuite()
    for test_class in test_cases:
        tests = loader.loadTestsFromTestCase(test_class)
        suite.addTests(tests)
    return suite

Если поиск начат в каталоге, содержащем пакет, — из командной строки или вызовом TestLoader.discover(), — то в пакете __init__.py будет выполнена проверка на наличие load_tests. Если такой функции нет, поиск продолжится рекурсивно в пакете, как если бы это был обычный каталог. В противном случае поиск тестов пакета будет поручен функции load_tests, которая вызывается со следующими аргументами:

load_tests(loader, standard_tests, pattern)

Она должна возвращать TestSuite, содержащий все тесты пакета. (standard_tests будет содержать только тесты, собранные из __init__.py.)

Поскольку шаблон передаётся в load_tests, пакет может продолжить (и, возможно, изменить) поиск тестов. Функция load_tests, которая ничего не делает, для пакета тестов может выглядеть так:

def load_tests(loader, standard_tests, pattern):
    # top level directory cached on loader instance
    this_dir = os.path.dirname(__file__)
    package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
    standard_tests.addTests(package_tests)
    return standard_tests

Изменено в версии 3.5: При поиске больше не проверяется соответствие имён пакетов шаблону pattern, поскольку имена пакетов не могут соответствовать шаблону по умолчанию.

Фикстуры классов и модулей

Фикстуры уровня класса и модуля реализованы в TestSuite. Когда набор тестов встречает тест из нового класса, вызывается tearDownClass() предыдущего класса (если он есть), а затем setUpClass() нового класса.

Аналогично, если тест относится к модулю, отличному от модуля предыдущего теста, сначала выполняется tearDownModule предыдущего модуля, а затем setUpModule нового модуля.

После выполнения всех тестов запускаются заключительные tearDownClass и tearDownModule.

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

По умолчанию загрузчики тестов unittest группируют тесты одного модуля и класса вместе. Благодаря этому setUpClass / setUpModule (и т. д.) вызываются ровно один раз для каждого класса и модуля. Если изменить порядок так, чтобы тесты из разных модулей и классов следовали друг за другом, эти общие функции фикстур могут вызываться несколько раз за один запуск тестов.

Общие фикстуры не предназначены для работы с наборами тестов, имеющими нестандартный порядок. Для сред, которым не нужны общие фикстуры, по-прежнему существует BaseTestSuite.

Если во время выполнения одной из общих функций фикстур возникает исключение, тест отмечается как завершившийся ошибкой. Поскольку соответствующего экземпляра теста нет, для представления ошибки создаётся объект _ErrorHolder (с тем же интерфейсом, что и у TestCase). Если вы используете стандартное средство запуска тестов unittest, эта деталь не имеет значения, но авторам сред она может быть полезна.

setUpClass и tearDownClass

Их следует реализовать как методы класса:

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()

Если вы хотите, чтобы setUpClass и tearDownClass базовых классов также вызывались, необходимо вызвать их самостоятельно. Реализации в TestCase пусты.

Если во время выполнения setUpClass возникает исключение, тесты класса не запускаются, а tearDownClass не выполняется. Для пропущенных классов setUpClass и tearDownClass выполняться не будут. Если исключение является исключением SkipTest, класс будет отмечен как пропущенный, а не как завершившийся ошибкой.

setUpModule и tearDownModule

Их следует реализовать как функции:

def setUpModule():
    createConnection()

def tearDownModule():
    closeConnection()

Если при выполнении setUpModule возникает исключение, тесты модуля не запускаются, а tearDownModule не выполняется. Если исключение является исключением SkipTest, модуль будет отмечен как пропущенный, а не как завершившийся ошибкой.

Чтобы добавить код очистки, который должен выполниться даже в случае исключения, используйте addModuleCleanup:

unittest.addModuleCleanup(function, /, *args, **kwargs)

Добавляет функцию, которая будет вызвана после tearDownModule() для освобождения ресурсов, использованных во время тестирования класса. Функции вызываются в порядке, обратном порядку их добавления (LIFO). При вызове им передаются позиционные и именованные аргументы, переданные в addModuleCleanup() при добавлении функции.

Если setUpModule() завершается неудачей, то есть tearDownModule() не вызывается, все добавленные функции очистки всё равно будут вызваны.

Добавлено в версии 3.8.

classmethod unittest.enterModuleContext(cm)

Входит в переданный менеджер контекста. Если вход выполнен успешно, добавляет его метод __exit__() в качестве функции очистки с помощью addModuleCleanup() и возвращает результат метода __enter__().

Добавлено в версии 3.11.

unittest.doModuleCleanups()

Эта функция безусловно вызывается после tearDownModule() или после setUpModule(), если setUpModule() вызывает исключение.

Она отвечает за вызов всех функций очистки, добавленных с помощью addModuleCleanup(). Если функции очистки должны вызываться до tearDownModule(), можно самостоятельно вызвать doModuleCleanups().

doModuleCleanups() извлекает методы из стека функций очистки по одному, поэтому её можно вызывать в любое время.

Добавлено в версии 3.8.

Обработка сигналов

Добавлено в версии 3.2.

Параметр командной строки unittest -c/--catch и параметр catchbreak функции unittest.main() обеспечивают более удобную обработку нажатия Ctrl-C во время выполнения тестов. При включённой обработке прерывания по Ctrl-C текущий тест завершается, затем выполнение набора тестов прекращается и выводятся все результаты, полученные к этому моменту. Повторное нажатие Ctrl-C вызывает KeyboardInterrupt обычным образом.

Обработчик сигнала Ctrl-C старается сохранять совместимость с кодом или тестами, которые устанавливают собственный обработчик signal.SIGINT. Если вызывается обработчик unittest, но он не является установленным обработчиком signal.SIGINT, то есть был заменён тестируемой системой, которая делегировала ему обработку, вызывается обработчик по умолчанию. Обычно именно такого поведения ожидает код, заменяющий установленный обработчик и делегирующий ему обработку. Для отдельных тестов, которым требуется отключить обработку Ctrl-C с помощью unittest, можно использовать декоратор removeHandler().

Авторам тестовых сред доступны несколько вспомогательных функций для включения обработки Ctrl-C в тестовых средах.

unittest.installHandler()

Устанавливает обработчик Ctrl-C. При получении signal.SIGINT (обычно в ответ на нажатие пользователем Ctrl-C) для всех зарегистрированных результатов вызывается stop().

unittest.registerResult(result)

Регистрирует объект TestResult для обработки Ctrl-C. При регистрации результата сохраняется слабая ссылка на него, поэтому сборка мусора по-прежнему может удалить результат.

Регистрация объекта TestResult не имеет побочных эффектов, если обработка Ctrl-C не включена. Поэтому тестовые среды могут безусловно регистрировать все создаваемые результаты независимо от того, включена ли обработка.

unittest.removeResult(result)

Удаляет зарегистрированный результат. После удаления результата метод stop() больше не будет вызываться для этого объекта в ответ на Ctrl-C.

unittest.removeHandler(function=None)

При вызове без аргументов эта функция удаляет обработчик Ctrl-C, если он был установлен. Функцию также можно использовать как декоратор теста, чтобы временно удалить обработчик на время выполнения теста:

@unittest.removeHandler
def test_signal_handling(self):
    ...

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/unittest.html

Spec-Zone.ru

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