unittest.md
1> **Источник:** https://python-all.ru/3.12/library/unittest.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `unittest` – фреймворк для модульного тестирования89**Исходный код:** [Lib/unittest/\_\_init\_\_.py](https://python-all.ru/src/3.12/Lib/unittest/__init__.py)1011---1213(Если вы уже знакомы с основными понятиями тестирования, можете перейти к [списку методов assert](https://python-all.ru/3.12/library/unittest.html#assert-methods).)1415Фреймворк модульного тестирования [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) изначально был вдохновлён JUnit и имеет схожий подход с основными фреймворками модульного тестирования на других языках. Он поддерживает автоматизацию тестов, совместное использование кода подготовки и завершения тестов, объединение тестов в коллекции и независимость тестов от системы отчётов.1617Для этого [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) поддерживает несколько важных концепций в объектно-ориентированном стиле:1819**тестовая фикстура**2021*Тестовая фикстура* представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, а также все связанные действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск серверного процесса.2223**тестовый случай**2425*Тестовый случай* – это отдельная единица тестирования. Он проверяет определённую реакцию на конкретный набор входных данных. [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) предоставляет базовый класс [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), который можно использовать для создания новых тестовых случаев.2627**набор тестов**2829*Набор тестов* – это совокупность тестовых случаев, наборов тестов или и того, и другого. Он используется для объединения тестов, которые должны выполняться вместе.3031**исполнитель тестов**3233*Исполнитель тестов* – это компонент, который управляет выполнением тестов и предоставляет результат пользователю. Исполнитель может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение, указывающее на результаты выполнения тестов.3435> **См. также**36>37> **Модуль [`doctest`](https://python-all.ru/3.12/library/doctest.html#module-doctest)**38>39> Ещё один модуль поддержки тестирования с совершенно другим подходом.40>41> **[Простое тестирование в Smalltalk: с шаблонами](https://python-all.ru/3.12/library/unittest.html)**42>43> Оригинальная статья Кента Бека о фреймворках тестирования, в которых используется тот же шаблон, что и в [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest).44>45> **[pytest](https://python-all.ru/3.12/library/unittest.html)**46>47> Сторонний фреймворк модульного тестирования с более лёгким синтаксисом для написания тестов. Например, `assert func(10) == 42`.48>49> **[Таксономия инструментов тестирования Python](https://python-all.ru/3.12/library/unittest.html)**50>51> Обширный список инструментов тестирования Python, включая фреймворки функционального тестирования и библиотеки имитационных объектов (mock).52>53> **[Список рассылки по тестированию в Python](https://python-all.ru/3.12/library/unittest.html)**54>55> Группа по интересам для обсуждения тестирования и инструментов тестирования в Python.56>57> Скрипт `Tools/unittestgui/unittestgui.py` в дистрибутиве исходных кодов Python – это графический инструмент для обнаружения и выполнения тестов. Он в значительной степени предназначен для упрощения работы с тестированием для новичков в модульном тестировании. Для производственных сред рекомендуется, чтобы тесты запускались системой непрерывной интеграции, такой как [Buildbot](https://python-all.ru/3.12/library/unittest.html), [Jenkins](https://python-all.ru/3.12/library/unittest.html), [GitHub Actions](https://python-all.ru/3.12/library/unittest.html) или [AppVeyor](https://python-all.ru/3.12/library/unittest.html).5859## Простой пример6061Модуль [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) предоставляет богатый набор инструментов для создания и запуска тестов. В этом разделе показано, что небольшого подмножества этих инструментов достаточно для удовлетворения потребностей большинства пользователей.6263Вот короткий скрипт для тестирования трёх строковых методов:6465```python66import unittest6768class TestStringMethods(unittest.TestCase):6970 def test_upper(self):71 self.assertEqual('foo'.upper(), 'FOO')7273 def test_isupper(self):74 self.assertTrue('FOO'.isupper())75 self.assertFalse('Foo'.isupper())7677 def test_split(self):78 s = 'hello world'79 self.assertEqual(s.split(), ['hello', 'world'])80 # проверить, что s.split завершается ошибкой, если разделитель не строка81 with self.assertRaises(TypeError):82 s.split(2)8384if __name__ == '__main__':85 unittest.main()86```8788Тестовый случай создаётся созданием подкласса [`unittest.TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase). Три отдельных теста определяются методами, имена которых начинаются с букв `test`. Это соглашение об именовании сообщает тестовому раннеру, какие методы являются тестами.8990Суть каждого теста – вызов [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual) для проверки ожидаемого результата; [`assertTrue()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertTrue) или [`assertFalse()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertFalse) для проверки условия; или [`assertRaises()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaises) для проверки того, что возбуждается определённое исключение. Эти методы используются вместо оператора [`assert`](https://python-all.ru/3.12/reference/simple_stmts.html#assert), чтобы исполнитель тестов мог накапливать все результаты тестов и формировать отчёт.9192Методы [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) и [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown) позволяют определить инструкции, которые будут выполняться до и после каждого метода теста. Они подробнее рассматриваются в разделе [Организация тестового кода](https://python-all.ru/3.12/library/unittest.html#organizing-tests).9394В последнем блоке показан простой способ запуска тестов. [`unittest.main()`](https://python-all.ru/3.12/library/unittest.html#unittest.main) предоставляет интерфейс командной строки для тестового скрипта. При запуске из командной строки приведённый выше скрипт выдаёт вывод, который выглядит так:9596```python97...98----------------------------------------------------------------------99Ran 3 tests in 0.000s100101OK102```103104Передача флага `-v` вашему тестовому скрипту укажет [`unittest.main()`](https://python-all.ru/3.12/library/unittest.html#unittest.main) включить более высокий уровень подробности и выдать следующий вывод:105106```python107test_isupper (__main__.TestStringMethods.test_isupper) ... ok108test_split (__main__.TestStringMethods.test_split) ... ok109test_upper (__main__.TestStringMethods.test_upper) ... ok110111----------------------------------------------------------------------112Ran 3 tests in 0.001s113114OK115```116117Представленные выше примеры демонстрируют наиболее часто используемые возможности [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest), которых достаточно для многих повседневных задач тестирования. Оставшаяся часть документации рассматривает полный набор функций с самого начала.118119Изменено в версии 3.11: Возврат значения из тестового метода (кроме значения по умолчанию `None`) теперь считается устаревшим.120121## Интерфейс командной строки122123Модуль unittest можно использовать из командной строки для запуска тестов из модулей, классов или даже отдельных тестовых методов:124125```python126python -m unittest test_module1 test_module2127python -m unittest test_module.TestClass128python -m unittest test_module.TestClass.test_method129```130131Можно передать список с любой комбинацией имён модулей, а также полных имён классов или методов.132133Тестовые модули также можно указывать по пути к файлу:134135```python136python -m unittest tests/test_something.py137```138139Это позволяет использовать автодополнение имён файлов в оболочке для указания тестового модуля. Указанный файл по-прежнему должен быть импортируем как модуль. Путь преобразуется в имя модуля путём удаления ‘.py’ и замены разделителей пути на ‘.’. Если требуется выполнить тестовый файл, который не импортируется как модуль, следует запускать файл напрямую.140141Можно запускать тесты с большей детализацией (повышенной подробностью), передав флаг -v:142143```python144python -m unittest -v test_module145```146147При запуске без аргументов запускается [автоматическое обнаружение тестов](https://python-all.ru/3.12/library/unittest.html#unittest-test-discovery):148149```python150python -m unittest151```152153Чтобы получить список всех параметров командной строки:154155```python156python -m unittest -h157```158159Изменено в версии 3.2: В более ранних версиях можно было запускать только отдельные тестовые методы, а не модули или классы.160161### Параметры командной строки162163**unittest** поддерживает следующие параметры командной строки:164165#### `-b, --buffer`166167Потоки стандартного вывода и стандартной ошибки буферизируются во время выполнения теста. Вывод при успешном тесте отбрасывается. При ошибке или провале теста вывод выводится обычным образом и добавляется к сообщениям о неудаче.168169#### `-c, --catch`170171`Control`-`C` во время выполнения теста ожидает завершения текущего теста и затем выводит все результаты на данный момент. Повторное нажатие `Control`-`C` вызывает обычное исключение [`KeyboardInterrupt`](https://python-all.ru/3.12/library/exceptions.html#KeyboardInterrupt).172173См. раздел [Обработка сигналов](https://python-all.ru/3.12/library/unittest.html#signal-handling) с описанием функций, предоставляющих эту возможность.174175#### `-f, --failfast`176177Остановить выполнение теста при первой же ошибке или неудаче.178179#### `-k`180181Запускать только те тестовые методы и классы, которые соответствуют шаблону или подстроке. Этот параметр можно использовать несколько раз; в этом случае включаются все тесты, соответствующие любому из заданных шаблонов.182183Шаблоны, содержащие символ подстановки (`*`), сопоставляются с именем теста с помощью [`fnmatch.fnmatchcase()`](https://python-all.ru/3.12/library/fnmatch.html#fnmatch.fnmatchcase); в противном случае используется простое сопоставление подстрок с учётом регистра.184185Шаблоны сопоставляются с полным именем тестового метода, импортированным загрузчиком тестов.186187Например, `-k foo` соответствует `foo_tests.SomeTest.test_something`, `bar_tests.SomeTest.test_foo`, но не `bar_tests.FooTest.test_something`.188189#### `--locals`190191Показывать локальные переменные в трассировках.192193#### `--durations N`194195Показывать N самых медленных тестов (N=0 – все).196197Добавлено в версии 3.2: Были добавлены параметры командной строки `-b`, `-c` и `-f`.198199Добавлено в версии 3.5: Параметр командной строки `--locals`.200201Добавлено в версии 3.7: Параметр командной строки `-k`.202203Добавлено в версии 3.12: Параметр командной строки `--durations`.204205Командная строка также может использоваться для автоматического обнаружения тестов, для запуска всех тестов в проекте или только их части.206207## Обнаружение тестов208209Добавлено в версии 3.2.210211Unittest поддерживает простое обнаружение тестов. Чтобы быть совместимыми с обнаружением тестов, все тестовые файлы должны быть [модулями](https://python-all.ru/3.12/tutorial/modules.html#tut-modules) или [пакетами](https://python-all.ru/3.12/tutorial/modules.html#tut-packages), импортируемыми из корневого каталога проекта (это означает, что их имена файлов должны быть допустимыми [идентификаторами](https://python-all.ru/3.12/reference/lexical_analysis.html#identifiers)).212213Обнаружение тестов реализовано в [`TestLoader.discover()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader.discover), но также может использоваться из командной строки. Основное использование командной строки:214215```python216cd project_directory217python -m unittest discover218```219220> **Примечание**221>222> В качестве сокращения, `python -m unittest` эквивалентно `python -m unittest discover`. Если требуется передать аргументы для обнаружения тестов, необходимо явно указать подкоманду `discover`.223224Подкоманда `discover` имеет следующие опции:225226#### `-v, --verbose`227228Подробный вывод229230#### `-s, --start-directory directory`231232Каталог для начала обнаружения (по умолчанию `.`)233234#### `-p, --pattern pattern`235236Шаблон для сопоставления тестовых файлов (по умолчанию `test*.py`)237238#### `-t, --top-level-directory directory`239240Корневой каталог проекта (по умолчанию – каталог начала поиска)241242Параметры [`-s`](https://python-all.ru/3.12/library/unittest.html#cmdoption-unittest-discover-s), [`-p`](https://python-all.ru/3.12/library/unittest.html#cmdoption-unittest-discover-p) и [`-t`](https://python-all.ru/3.12/library/unittest.html#cmdoption-unittest-discover-t) можно передавать в качестве позиционных аргументов в указанном порядке. Следующие две командные строки эквивалентны:243244```python245python -m unittest discover -s project_directory -p "*_test.py"246python -m unittest discover project_directory "*_test.py"247```248249Помимо пути, в качестве начального каталога можно передать имя пакета, например `myproject.subpackage.test`. Указанное имя пакета будет импортировано, и его расположение в файловой системе будет использоваться в качестве начального каталога.250251> **Внимание**252>253> Обнаружение тестов загружает тесты путем их импорта. Как только обнаружение тестов найдет все тестовые файлы в указанном начальном каталоге, оно преобразует пути в имена пакетов для импорта. Например, `foo/bar/baz.py` будет импортирован как `foo.bar.baz`.254>255> Если пакет установлен глобально, и предпринимается попытка обнаружения тестов в другой копии пакета, то импорт *может* произойти из неправильного места. Если это произойдет, обнаружение тестов выдаст предупреждение и завершится.256>257> Если указать начальный каталог как имя пакета, а не путь к каталогу, то discover считает, что местоположение, из которого он импортирует, и есть то, которое вы имели в виду, поэтому предупреждение не появится.258259Тестовые модули и пакеты могут настраивать загрузку и обнаружение тестов с помощью [протокола load\_tests](https://python-all.ru/3.12/library/unittest.html#id1).260261Изменено в версии 3.4: Обнаружение тестов поддерживает [пакеты пространств имён](https://python-all.ru/3.12/glossary.html#term-namespace-package) для начального каталога. Обратите внимание: нужно указать также каталог верхнего уровня (например, `python -m unittest discover -s root/namespace -t root`).262263Изменено в версии 3.11: [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) убрана поддержка [пакетов пространств имён](https://python-all.ru/3.12/glossary.html#term-namespace-package) в Python 3.11. Она была сломана начиная с Python 3.7. Начальный каталог и подкаталоги, содержащие тесты, должны быть обычными пакетами, имеющими `__init__.py` файл.264265Каталоги, содержащие начальный каталог, всё ещё могут быть пакетом пространства имён. В этом случае нужно указать начальный каталог как точечное имя пакета, а целевой каталог – явно. Например:266267```python268# proj/ <-- текущая директория269# namespace/270# mypkg/271# __init__.py272# test_mypkg.py273274python -m unittest discover -s namespace.mypkg -t .275```276277## Организация тестового кода278279Основными строительными блоками модульного тестирования являются *тестовые случаи* – отдельные сценарии, которые необходимо настроить и проверить на корректность. В [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) тестовые случаи представлены экземплярами [`unittest.TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase). Чтобы создать собственные тестовые случаи, необходимо написать подклассы [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) или использовать [`FunctionTestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.FunctionTestCase).280281Тестовый код экземпляра [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) должен быть полностью самодостаточным, чтобы его можно было запускать как изолированно, так и в произвольной комбинации с любым количеством других тестовых случаев.282283Простейший подкласс [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) просто реализует тестовый метод (т.е. метод, имя которого начинается с `test`) для выполнения определенного тестового кода:284285```python286import unittest287288class DefaultWidgetSizeTestCase(unittest.TestCase):289 def test_default_widget_size(self):290 widget = Widget('The widget')291 self.assertEqual(widget.size(), (50, 50))292```293294Обратите внимание, что для проверки чего-либо используются [методы assert\*](https://python-all.ru/3.12/library/unittest.html#assert-methods), предоставляемые базовым классом [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase). Если тест не пройден, будет возбуждено исключение с пояснительным сообщением, и [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) определит тестовый случай как *сбой*. Любые другие исключения будут расцениваться как *ошибки*.295296Тестов может быть много, и их подготовка может быть повторяющейся. К счастью, можно вынести код подготовки в метод с именем [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp), который тестовый фреймворк будет автоматически вызывать для каждого запускаемого теста:297298```python299import unittest300301class WidgetTestCase(unittest.TestCase):302 def setUp(self):303 self.widget = Widget('The widget')304305 def test_default_widget_size(self):306 self.assertEqual(self.widget.size(), (50,50),307 'incorrect default size')308309 def test_widget_resize(self):310 self.widget.resize(100,150)311 self.assertEqual(self.widget.size(), (100,150),312 'wrong size after resize')313```314315> **Примечание**316>317> Порядок выполнения различных тестов определяется сортировкой имен тестовых методов в соответствии со встроенным порядком строк.318319Если метод [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) возбуждает исключение во время выполнения теста, фреймворк посчитает, что тест завершился ошибкой, и тестовый метод не будет выполнен.320321Аналогично, можно предоставить метод [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown), который выполняет очистку после выполнения тестового метода:322323```python324import unittest325326class WidgetTestCase(unittest.TestCase):327 def setUp(self):328 self.widget = Widget('The widget')329330 def tearDown(self):331 self.widget.dispose()332```333334Если [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) успешно выполнен, [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown) будет выполнен, независимо от того, завершился тестовый метод успешно или нет.335336Такое рабочее окружение для тестового кода называется *тестовой фикстурой*. Новый экземпляр TestCase создаётся как уникальная тестовая фикстура, используемая для выполнения каждого отдельного тестового метода. Таким образом, [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp), [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown) и `__init__()` будут вызываться один раз для каждого теста.337338Рекомендуется группировать тесты с помощью реализаций TestCase в соответствии с тестируемыми возможностями. [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) предоставляет для этого механизм: *набор тестов*, представленный классом [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) из модуля [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest). В большинстве случаев вызов [`unittest.main()`](https://python-all.ru/3.12/library/unittest.html#unittest.main) сделает всё правильно: соберёт все тестовые случаи модуля и выполнит их.339340Однако, если требуется настроить сборку набора тестов, это можно сделать самостоятельно:341342```python343def suite():344 suite = unittest.TestSuite()345 suite.addTest(WidgetTestCase('test_default_widget_size'))346 suite.addTest(WidgetTestCase('test_widget_resize'))347 return suite348349if __name__ == '__main__':350 runner = unittest.TextTestRunner()351 runner.run(suite())352```353354Определения тестовых случаев и наборов тестов можно размещать в тех же модулях, что и тестируемый код (например, `widget.py`), но есть несколько преимуществ в размещении тестового кода в отдельном модуле, например, `test_widget.py`:355356- Тестовый модуль можно запускать автономно из командной строки.357- Тестовый код проще отделить от поставляемого кода.358- Меньше соблазна изменять тестовый код, чтобы подогнать его под тестируемый код, без веской причины.359- Тестовый код должен изменяться гораздо реже, чем тестируемый код.360- Тестируемый код проще поддаётся рефакторингу.361- Тесты для модулей, написанных на C, всё равно должны быть в отдельных модулях – так почему бы не придерживаться этого подхода?362- Если стратегия тестирования меняется, нет необходимости изменять исходный код.363364## Повторное использование старого тестового кода365366Некоторые пользователи могут иметь существующий тестовый код, который они хотели бы запускать из [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest), не преобразовывая каждую старую тестовую функцию в подкласс [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase).367368По этой причине [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) предоставляет класс [`FunctionTestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.FunctionTestCase). Этот подкласс [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) можно использовать для обёртывания существующей тестовой функции. Также можно предоставить функции настройки (set-up) и завершения (tear-down).369370Рассмотрим следующую тестовую функцию:371372```python373def testSomething():374 something = makeSomething()375 assert something.name is not None376 # ...377```378379можно создать эквивалентный экземпляр тестового случая следующим образом, с опциональными методами настройки и завершения:380381```python382testcase = unittest.FunctionTestCase(testSomething,383 setUp=makeSomethingDB,384 tearDown=deleteSomethingDB)385```386387> **Примечание**388>389> Хотя [`FunctionTestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.FunctionTestCase) можно использовать для быстрого преобразования существующей тестовой базы в систему на основе [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest), этот подход не рекомендуется. Затрата времени на создание правильных подклассов [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) значительно упростит будущий рефакторинг тестов.390391В некоторых случаях существующие тесты могли быть написаны с использованием модуля [`doctest`](https://python-all.ru/3.12/library/doctest.html#module-doctest). В этом случае [`doctest`](https://python-all.ru/3.12/library/doctest.html#module-doctest) предоставляет класс `DocTestSuite`, который может автоматически создавать экземпляры [`unittest.TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) из существующих тестов на основе [`doctest`](https://python-all.ru/3.12/library/doctest.html#module-doctest).392393## Пропуск тестов и ожидаемые сбои394395Добавлено в версии 3.1.396397Unittest поддерживает пропуск отдельных тестовых методов и даже целых классов тестов. Кроме того, он поддерживает пометку теста как «ожидаемый сбой» – тест, который сломан и завершится неудачей, но не должен засчитываться как сбой в [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult).398399Пропуск теста – это просто использование [`skip()`](https://python-all.ru/3.12/library/unittest.html#unittest.skip) [декоратора](https://python-all.ru/3.12/glossary.html#term-decorator) или одного из его условных вариантов, вызов [`TestCase.skipTest()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.skipTest) внутри [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) или тестового метода, или непосредственное возбуждение [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest).400401Базовый пропуск выглядит так:402403```python404class MyTestCase(unittest.TestCase):405406 @unittest.skip("demonstrating skipping")407 def test_nothing(self):408 self.fail("shouldn't happen")409410 @unittest.skipIf(mylib.__version__ < (1, 3),411 "not supported in this library version")412 def test_format(self):413 # Тесты, которые работают только для определённой версии библиотеки.414 pass415416 @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")417 def test_windows_support(self):418 # код тестирования для Windows419 pass420421 def test_maybe_skipped(self):422 if not external_resource_available():423 self.skipTest("external resource not available")424 # тестовый код, зависящий от внешнего ресурса425 pass426```427428Это вывод приведённого выше примера в подробном режиме:429430```python431test_format (__main__.MyTestCase.test_format) ... skipped 'not supported in this library version'432test_nothing (__main__.MyTestCase.test_nothing) ... skipped 'demonstrating skipping'433test_maybe_skipped (__main__.MyTestCase.test_maybe_skipped) ... skipped 'external resource not available'434test_windows_support (__main__.MyTestCase.test_windows_support) ... skipped 'requires Windows'435436----------------------------------------------------------------------437Ran 4 tests in 0.005s438439OK (skipped=4)440```441442Классы можно пропускать так же, как методы:443444```python445@unittest.skip("showing class skipping")446class MySkippedTestCase(unittest.TestCase):447 def test_not_run(self):448 pass449```450451[`TestCase.setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) также может пропустить тест. Это полезно, когда ресурс, который необходимо настроить, недоступен.452453Для ожидаемых сбоев используется декоратор [`expectedFailure()`](https://python-all.ru/3.12/library/unittest.html#unittest.expectedFailure).454455```python456class ExpectedFailureTestCase(unittest.TestCase):457 @unittest.expectedFailure458 def test_fail(self):459 self.assertEqual(1, 0, "broken")460```461462Легко создать собственные декораторы пропуска, создав декоратор, который вызывает [`skip()`](https://python-all.ru/3.12/library/unittest.html#unittest.skip) для теста, когда нужно его пропустить. Этот декоратор пропускает тест, если только переданный объект не имеет определённого атрибута:463464```python465def skipUnlessHasattr(obj, attr):466 if hasattr(obj, attr):467 return lambda func: func468 return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))469```470471Следующие декораторы и исключение реализуют пропуск тестов и ожидаемые сбои:472473#### `@unittest.skip(reason)`474475Безусловно пропускает декорированный тест. Параметр *reason* должен описывать причину пропуска теста.476477#### `@unittest.skipIf(condition, reason)`478479Пропустить декорированный тест, если *condition* истинно.480481#### `@unittest.skipUnless(condition, reason)`482483Пропустить декорированный тест, если *condition* не истинно.484485#### `@unittest.expectedFailure`486487Помечает тест как ожидаемый сбой или ошибку. Если тест завершается ошибкой или сбоем в самой тестовой функции (а не в одном из методов *тестовой фикстуры*), то он будет считаться успешным. Если тест проходит, он будет считаться неудачным.488489#### `exception unittest.SkipTest(reason)`490491Это исключение возбуждается для пропуска теста.492493Обычно можно использовать [`TestCase.skipTest()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.skipTest) или один из декораторов пропуска, вместо того чтобы возбуждать его напрямую.494495Пропущенные тесты не будут выполнять [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) или [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown). Пропущенные классы не будут выполнять [`setUpClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUpClass) или [`tearDownClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDownClass). Пропущенные модули не будут выполнять `setUpModule()` или `tearDownModule()`.496497## Различение итераций теста с помощью подтестов498499Добавлено в версии 3.4.500501Когда между тестами есть очень небольшие различия, например некоторые параметры, unittest позволяет различать их внутри тела тестового метода с помощью контекстного менеджера [`subTest()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.subTest).502503Например, следующий тест:504505```python506class NumbersTest(unittest.TestCase):507508 def test_even(self):509 """510 Проверить, что все числа от 0 до 5 чётные.511 """512 for i in range(0, 6):513 with self.subTest(i=i):514 self.assertEqual(i % 2, 0)515```516517выдаст следующий результат:518519```python520======================================================================521FAIL: test_even (__main__.NumbersTest.test_even) (i=1)522Test that numbers between 0 and 5 are all even.523----------------------------------------------------------------------524Traceback (most recent call last):525 File "subtests.py", line 11, in test_even526 self.assertEqual(i % 2, 0)527 ^^^^^^^^^^^^^^^^^^^^^^^^^^528AssertionError: 1 != 0529530======================================================================531FAIL: test_even (__main__.NumbersTest.test_even) (i=3)532Test that numbers between 0 and 5 are all even.533----------------------------------------------------------------------534Traceback (most recent call last):535 File "subtests.py", line 11, in test_even536 self.assertEqual(i % 2, 0)537 ^^^^^^^^^^^^^^^^^^^^^^^^^^538AssertionError: 1 != 0539540======================================================================541FAIL: test_even (__main__.NumbersTest.test_even) (i=5)542Test that numbers between 0 and 5 are all even.543----------------------------------------------------------------------544Traceback (most recent call last):545 File "subtests.py", line 11, in test_even546 self.assertEqual(i % 2, 0)547 ^^^^^^^^^^^^^^^^^^^^^^^^^^548AssertionError: 1 != 0549```550551Без использования подтеста выполнение остановилось бы после первого сбоя, и ошибку было бы труднее диагностировать, поскольку значение `i` не отображалось бы:552553```python554======================================================================555FAIL: test_even (__main__.NumbersTest.test_even)556----------------------------------------------------------------------557Traceback (most recent call last):558 File "subtests.py", line 32, in test_even559 self.assertEqual(i % 2, 0)560AssertionError: 1 != 0561```562563## Классы и функции564565В этом разделе подробно описывается API [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest).566567### Тестовые примеры568569#### `class unittest.TestCase(methodName='runTest')`570571Экземпляры класса [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) представляют собой логические тестовые единицы в среде [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest). Этот класс предназначен для использования в качестве базового класса, при этом конкретные тесты реализуются в конкретных подклассах. Класс реализует интерфейс, необходимый тестовому исполнителю для управления тестами, а также методы, которые тестовый код может использовать для проверки и сообщения о различных видах сбоев.572573Каждый экземпляр [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) выполняет один базовый метод: метод с именем *methodName*. В большинстве случаев использования [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) не требуется ни изменять *methodName*, ни переопределять метод по умолчанию `runTest()`.574575Изменено в версии 3.2: [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) можно успешно создать без указания *methodName*. Это упрощает эксперименты с [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) в интерактивном интерпретаторе.576577Экземпляры [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) предоставляют три группы методов: одна группа используется для выполнения теста, другая – реализацией теста для проверки условий и сообщения о сбоях, и несколько запросных методов, позволяющих собирать информацию о самом тесте.578579Методы первой группы (выполнение теста):580581#### `setUp()`582583Метод, вызываемый для подготовки тестовой фикстуры. Он вызывается непосредственно перед вызовом тестового метода; за исключением [`AssertionError`](https://python-all.ru/3.12/library/exceptions.html#AssertionError) или [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest), любое исключение, возбуждённое этим методом, будет считаться ошибкой, а не сбоем теста. Реализация по умолчанию ничего не делает.584585#### `tearDown()`586587Метод, вызываемый сразу после вызова тестового метода и записи результата. Он вызывается, даже если тестовый метод возбудил исключение, поэтому реализация в подклассах должна быть особенно осторожна при проверке внутреннего состояния. Любое исключение, кроме [`AssertionError`](https://python-all.ru/3.12/library/exceptions.html#AssertionError) или [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest), возбуждённое этим методом, будет считаться дополнительной ошибкой, а не сбоем теста (таким образом увеличивая общее количество сообщённых ошибок). Этот метод будет вызван только если [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) выполнится успешно, независимо от результата тестового метода. Реализация по умолчанию ничего не делает.588589#### `setUpClass()`590591Метод класса, вызываемый перед выполнением тестов в отдельном классе. `setUpClass` вызывается с классом в качестве единственного аргумента и должен быть декорирован как [`classmethod()`](https://python-all.ru/3.12/library/functions.html#classmethod):592593```python594@classmethod595def setUpClass(cls):596 ...597```598599См. [Фикстуры классов и модулей](https://python-all.ru/3.12/library/unittest.html#class-and-module-fixtures) для получения дополнительных сведений.600601Добавлено в версии 3.2.602603#### `tearDownClass()`604605Метод класса, вызываемый после выполнения тестов в отдельном классе. `tearDownClass` вызывается с классом в качестве единственного аргумента и должен быть декорирован как [`classmethod()`](https://python-all.ru/3.12/library/functions.html#classmethod):606607```python608@classmethod609def tearDownClass(cls):610 ...611```612613См. [Фикстуры классов и модулей](https://python-all.ru/3.12/library/unittest.html#class-and-module-fixtures) для получения дополнительных сведений.614615Добавлено в версии 3.2.616617#### `run(result=None)`618619Запускает тест, собирая результат в объект [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult), переданный как *result*. Если *result* опущен или равен `None`, создаётся временный объект результата (путем вызова метода [`defaultTestResult()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.defaultTestResult)), который и используется. Объект результата возвращается вызывающему коду [`run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.run).620621Того же эффекта можно добиться простым вызовом экземпляра [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase).622623Изменено в версии 3.3: Предыдущие версии `run` не возвращали результат. Также не возвращал результат вызов экземпляра.624625#### `skipTest(reason)`626627Вызов этого метода внутри тестового метода или [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) пропускает текущий тест. Подробнее см. [Пропуск тестов и ожидаемые сбои](https://python-all.ru/3.12/library/unittest.html#unittest-skipping).628629Добавлено в версии 3.1.630631#### `subTest(msg=None, **params)`632633Возвращает менеджер контекста, который выполняет вложенный блок кода как подтест. *msg* и *params* – необязательные произвольные значения, отображаемые при сбое подтеста, что позволяет однозначно их идентифицировать.634635Тестовый пример может содержать любое количество объявлений подтестов, и они могут быть произвольно вложены.636637Подробнее см. [Различение итераций тестов с помощью подтестов](https://python-all.ru/3.12/library/unittest.html#subtests).638639Добавлено в версии 3.4.640641#### `debug()`642643Запускает тест без сбора результата. Это позволяет исключениям, возникшим в тесте, распространяться до вызывающего кода, и может использоваться для поддержки запуска тестов под отладчиком.644645Класс [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) предоставляет несколько методов assert для проверки и сообщения об ошибках. В следующей таблице перечислены наиболее часто используемые методы (см. таблицы ниже для получения дополнительных методов assert):646647| Метод | Проверяет, что | Новое в |648| --- | --- | --- |649| [`assertEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual) | `a == b` | |650| [`assertNotEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertNotEqual) | `a != b` | |651| [`assertTrue(x)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertTrue) | `bool(x) is True` | |652| [`assertFalse(x)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertFalse) | `bool(x) is False` | |653| [`assertIs(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertIs) | `a is b` | 3.1 |654| [`assertIsNot(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertIsNot) | `a is not b` | 3.1 |655| [`assertIsNone(x)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertIsNone) | `x is None` | 3.1 |656| [`assertIsNotNone(x)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertIsNotNone) | `x is not None` | 3.1 |657| [`assertIn(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertIn) | `a in b` | 3.1 |658| [`assertNotIn(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertNotIn) | `a not in b` | 3.1 |659| [`assertIsInstance(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertIsInstance) | `isinstance(a, b)` | 3.2 |660| [`assertNotIsInstance(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertNotIsInstance) | `not isinstance(a, b)` | 3.2 |661662Все методы assert принимают аргумент *msg*, который, если указан, используется как сообщение об ошибке в случае сбоя (см. также [`longMessage`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.longMessage)). Обратите внимание, что ключевой аргумент *msg* может быть передан методам [`assertRaises()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaises), [`assertRaisesRegex()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaisesRegex), [`assertWarns()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertWarns), [`assertWarnsRegex()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertWarnsRegex) только когда они используются как менеджер контекста.663664#### `assertEqual(first, second, msg=None)`665666Проверяет, что *first* и *second* равны. Если значения не равны, тест завершится с ошибкой.667668Кроме того, если *first* и *second* относятся к одному и тому же типу и это list, tuple, dict, set, frozenset, str или любой тип, зарегистрированный подклассом с помощью [`addTypeEqualityFunc()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.addTypeEqualityFunc), то будет вызвана типовая функция сравнения для формирования более информативного сообщения об ошибке по умолчанию (см. также [список типовых методов](https://python-all.ru/3.12/library/unittest.html#type-specific-methods)).669670Изменено в версии 3.1: Добавлен автоматический вызов типовой функции сравнения.671672Изменено в версии 3.2: [`assertMultiLineEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertMultiLineEqual) добавлен в качестве типовой функции сравнения по умолчанию для сравнения строк.673674#### `assertNotEqual(first, second, msg=None)`675676Проверяет, что *first* и *second* не равны. Если значения равны, тест завершится с ошибкой.677678#### `assertTrue(expr, msg=None)`679680#### `assertFalse(expr, msg=None)`681682Проверяет, что *expr* истинно (или ложно).683684Обратите внимание, что это эквивалентно `bool(expr) is True`, а не `expr is True` (для последнего используйте `assertIs(expr, True)`). Этот метод также следует избегать, если доступны более специфические методы (например, `assertEqual(a, b)` вместо `assertTrue(a == b)`), потому что они предоставляют более информативное сообщение об ошибке в случае сбоя.685686#### `assertIs(first, second, msg=None)`687688#### `assertIsNot(first, second, msg=None)`689690Проверяет, что *first* и *second* являются (или не являются) одним и тем же объектом.691692Добавлено в версии 3.1.693694#### `assertIsNone(expr, msg=None)`695696#### `assertIsNotNone(expr, msg=None)`697698Проверяет, что *expr* является (или не является) `None`.699700Добавлено в версии 3.1.701702#### `assertIn(member, container, msg=None)`703704#### `assertNotIn(member, container, msg=None)`705706Проверяет, что *member* находится (или не находится) в *container*.707708Добавлено в версии 3.1.709710#### `assertIsInstance(obj, cls, msg=None)`711712#### `assertNotIsInstance(obj, cls, msg=None)`713714Проверяет, что *obj* является (или не является) экземпляром *cls* (который может быть классом или кортежем классов, как поддерживается [`isinstance()`](https://python-all.ru/3.12/library/functions.html#isinstance)). Для проверки точного типа используйте [`assertIs(type(obj), cls)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertIs).715716Добавлено в версии 3.2.717718Также можно проверить возникновение исключений, предупреждений и сообщений журнала с помощью следующих методов:719720| Метод | Проверяет, что | Новое в |721| --- | --- | --- |722| [`assertRaises(exc, fun, *args, **kwds)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaises) | `fun(*args, **kwds)` возбуждает *exc* | |723| [`assertRaisesRegex(exc, r, fun, *args, **kwds)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaisesRegex) | `fun(*args, **kwds)` возбуждает *exc* и сообщение соответствует регулярному выражению *r* | 3.1 |724| [`assertWarns(warn, fun, *args, **kwds)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertWarns) | `fun(*args, **kwds)` возбуждает *warn* | 3.2 |725| [`assertWarnsRegex(warn, r, fun, *args, **kwds)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertWarnsRegex) | `fun(*args, **kwds)` возбуждает *warn* и сообщение соответствует регулярному выражению *r* | 3.2 |726| [`assertLogs(logger, level)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertLogs) | Блок `with` пишет в журнал *logger* с минимальным уровнем *level* | 3.4 |727| [`assertNoLogs(logger, level)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertNoLogs) | Блок `with` не пишет в журнал*logger* с минимальным *level* | 3.10 |728729#### `assertRaises(exception, callable, *args, **kwds)`730731#### `assertRaises(exception, *, msg=None)`732733Проверяет, что исключение возбуждается, когда *callable* вызывается с любыми позиционными или именованными аргументами, которые также передаются в [`assertRaises()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaises). Тест проходит, если возбуждается *исключение*, считается ошибкой, если возбуждается другое исключение, или не проходит, если исключение не возбуждается. Чтобы перехватить любое из группы исключений, можно передать кортеж, содержащий классы исключений, как *исключение*.734735Если переданы только аргументы *исключение* и, возможно, *msg*, возвращается менеджер контекста, чтобы проверяемый код можно было написать встроенно, а не в виде функции:736737```python738with self.assertRaises(SomeException):739 do_something()740```741742При использовании в качестве менеджера контекста [`assertRaises()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaises) принимает дополнительный ключевой аргумент *msg*.743744Менеджер контекста сохраняет перехваченный объект исключения в своём атрибуте `exception`. Это может быть полезно, если нужно выполнить дополнительные проверки возникшего исключения:745746```python747with self.assertRaises(SomeException) as cm:748 do_something()749750the_exception = cm.exception751self.assertEqual(the_exception.error_code, 3)752```753754Изменено в версии 3.1: Добавлена возможность использовать [`assertRaises()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaises) в качестве менеджера контекста.755756Изменено в версии 3.2: Добавлен атрибут `exception`.757758Изменено в версии 3.3: добавлен ключевой аргумент *msg* при использовании в качестве менеджера контекста.759760#### `assertRaisesRegex(exception, regex, callable, *args, **kwds)`761762#### `assertRaisesRegex(exception, regex, *, msg=None)`763764Как [`assertRaises()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaises), но также проверяет, что *regex* соответствует строковому представлению возбуждённого исключения. *regex* может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования [`re.search()`](https://python-all.ru/3.12/library/re.html#re.search). Примеры:765766```python767self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$",768 int, 'XYZ')769```770771или:772773```python774with self.assertRaisesRegex(ValueError, 'literal'):775 int('XYZ')776```777778Добавлено в версии 3.1: Добавлено под именем `assertRaisesRegexp`.779780Изменено в версии 3.2: переименовано в [`assertRaisesRegex()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRaisesRegex).781782Изменено в версии 3.3: добавлен ключевой аргумент *msg* при использовании в качестве менеджера контекста.783784#### `assertWarns(warning, callable, *args, **kwds)`785786#### `assertWarns(warning, *, msg=None)`787788Проверяет, что предупреждение вызывается, когда *вызываемый объект* вызывается с любыми позиционными или ключевыми аргументами, которые также передаются в [`assertWarns()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertWarns). Тест проходит, если *предупреждение* вызывается, и не проходит в противном случае. Любое исключение считается ошибкой. Чтобы перехватить любое из группы предупреждений, можно передать кортеж, содержащий классы предупреждений, в качестве *предупреждения*.789790Если указаны только *предупреждение* и, возможно, *msg*, возвращается менеджер контекста, позволяющий писать тестируемый код inline, а не в виде функции:791792```python793with self.assertWarns(SomeWarning):794 do_something()795```796797При использовании в качестве менеджера контекста [`assertWarns()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertWarns) принимает дополнительный ключевой аргумент *msg*.798799Менеджер контекста сохраняет перехваченный объект предупреждения в своём атрибуте `warning`, а также исходную строку, вызвавшую предупреждения, в атрибутах `filename` и `lineno`. Это может быть полезно, если требуется выполнить дополнительные проверки перехваченного предупреждения:800801```python802with self.assertWarns(SomeWarning) as cm:803 do_something()804805self.assertIn('myfile.py', cm.filename)806self.assertEqual(320, cm.lineno)807```808809Этот метод работает независимо от фильтров предупреждений, установленных на момент его вызова.810811Добавлено в версии 3.2.812813Изменено в версии 3.3: добавлен ключевой аргумент *msg* при использовании в качестве менеджера контекста.814815#### `assertWarnsRegex(warning, regex, callable, *args, **kwds)`816817#### `assertWarnsRegex(warning, regex, *, msg=None)`818819Как и [`assertWarns()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertWarns), но также проверяет, что *регулярное выражение* соответствует сообщению вызванного предупреждения. *Регулярное выражение* может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, пригодное для использования [`re.search()`](https://python-all.ru/3.12/library/re.html#re.search). Пример:820821```python822self.assertWarnsRegex(DeprecationWarning,823 r'legacy_function\(\) is deprecated',824 legacy_function, 'XYZ')825```826827или:828829```python830with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):831 frobnicate('/etc/passwd')832```833834Добавлено в версии 3.2.835836Изменено в версии 3.3: добавлен ключевой аргумент *msg* при использовании в качестве менеджера контекста.837838#### `assertLogs(logger=None, level=None)`839840Менеджер контекста для проверки того, что хотя бы одно сообщение зарегистрировано в *логгере* или одном из его потомков, с уровнем не ниже указанного *уровня*.841842Если указан, *логгер* должен быть объектом [`logging.Logger`](https://python-all.ru/3.12/library/logging.html#logging.Logger) или [`str`](https://python-all.ru/3.12/library/stdtypes.html#str), задающим имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения, не заблокированные непропагандирующим дочерним логгером.843844Если указан, *уровень* должен быть числовым уровнем логирования или его строковым эквивалентом (например, `"ERROR"` или [`logging.ERROR`](https://python-all.ru/3.12/library/logging.html#logging.ERROR)). По умолчанию [`logging.INFO`](https://python-all.ru/3.12/library/logging.html#logging.INFO).845846Тест проходит, если хотя бы одно сообщение, отправленное внутри блока `with`, соответствует условиям *логгера* и *уровня*, в противном случае тест не проходит.847848Объект, возвращаемый менеджером контекста, представляет собой вспомогательный объект для записи, который отслеживает соответствующие сообщения журнала. Он имеет два атрибута:849850#### `records`851852Список объектов [`logging.LogRecord`](https://python-all.ru/3.12/library/logging.html#logging.LogRecord) соответствующих сообщений журнала.853854#### `output`855856Список объектов [`str`](https://python-all.ru/3.12/library/stdtypes.html#str) с отформатированным выводом соответствующих сообщений.857858Пример:859860```python861with self.assertLogs('foo', level='INFO') as cm:862 logging.getLogger('foo').info('first message')863 logging.getLogger('foo.bar').error('second message')864self.assertEqual(cm.output, ['INFO:foo:first message',865 'ERROR:foo.bar:second message'])866```867868Добавлено в версии 3.4.869870#### `assertNoLogs(logger=None, level=None)`871872Менеджер контекста для проверки того, что на *логгере* или одном из его потомков не зарегистрировано ни одного сообщения с уровнем не ниже указанного *уровня*.873874Если указан, *логгер* должен быть объектом [`logging.Logger`](https://python-all.ru/3.12/library/logging.html#logging.Logger) или [`str`](https://python-all.ru/3.12/library/stdtypes.html#str), задающим имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения.875876Если указан, *уровень* должен быть числовым уровнем логирования или его строковым эквивалентом (например, `"ERROR"` или [`logging.ERROR`](https://python-all.ru/3.12/library/logging.html#logging.ERROR)). По умолчанию [`logging.INFO`](https://python-all.ru/3.12/library/logging.html#logging.INFO).877878В отличие от [`assertLogs()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertLogs), менеджер контекста ничего не возвращает.879880Добавлено в версии 3.10.881882Существуют также другие методы для выполнения более специфических проверок, например:883884| Метод | Проверяет, что | Новое в |885| --- | --- | --- |886| [`assertAlmostEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertAlmostEqual) | `round(a-b, 7) == 0` | |887| [`assertNotAlmostEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) | `round(a-b, 7) != 0` | |888| [`assertGreater(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertGreater) | `a > b` | 3.1 |889| [`assertGreaterEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertGreaterEqual) | `a >= b` | 3.1 |890| [`assertLess(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertLess) | `a < b` | 3.1 |891| [`assertLessEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertLessEqual) | `a <= b` | 3.1 |892| [`assertRegex(s, r)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRegex) | `r.search(s)` | 3.1 |893| [`assertNotRegex(s, r)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertNotRegex) | `not r.search(s)` | 3.2 |894| [`assertCountEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertCountEqual) | *a* и *b* содержат одинаковые элементы в одинаковом количестве, независимо от их порядка. | 3.2 |895896#### `assertAlmostEqual(first, second, places=7, msg=None, delta=None)`897898#### `assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)`899900Проверяет, что *first* и *second* приблизительно равны (или не равны), вычисляя разность, округляя до заданного числа десятичных знаков *places* (по умолчанию 7) и сравнивая с нулём. Обратите внимание, что эти методы округляют значения до заданного числа *десятичных знаков* (т.е. как функция [`round()`](https://python-all.ru/3.12/library/functions.html#round)), а не до *значащих цифр*.901902Если указан *delta* вместо *places*, то разность между *first* и *second* должна быть меньше или равна (или больше) *delta*.903904Одновременная передача *delta* и *places* вызывает [`TypeError`](https://python-all.ru/3.12/library/exceptions.html#TypeError).905906Изменено в версии 3.2: [`assertAlmostEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertAlmostEqual) теперь автоматически считает приблизительно равными объекты, которые сравниваются как равные. [`assertNotAlmostEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) теперь автоматически завершается ошибкой, если объекты сравниваются как равные. Добавлен именованный аргумент *delta*.907908#### `assertGreater(first, second, msg=None)`909910#### `assertGreaterEqual(first, second, msg=None)`911912#### `assertLess(first, second, msg=None)`913914#### `assertLessEqual(first, second, msg=None)`915916Проверяет, что *first* соответственно \>, \>=, \< или \<= по отношению к *second* в зависимости от имени метода. Если это не так, тест завершается ошибкой:917918```python919>>> self.assertGreaterEqual(3, 4)920AssertionError: "3" unexpectedly not greater than or equal to "4"921```922923Добавлено в версии 3.1.924925#### `assertRegex(text, regex, msg=None)`926927#### `assertNotRegex(text, regex, msg=None)`928929Проверяет, что поиск по *regex* совпадает (или не совпадает) с *text*. В случае неудачи сообщение об ошибке будет содержать шаблон и *text* (или шаблон и ту часть *text*, которая неожиданно совпала). *regex* может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования с [`re.search()`](https://python-all.ru/3.12/library/re.html#re.search).930931Добавлено в версии 3.1: Добавлено под именем `assertRegexpMatches`.932933Изменено в версии 3.2: Метод `assertRegexpMatches()` был переименован в [`assertRegex()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertRegex).934935Добавлено в версии 3.2: [`assertNotRegex()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertNotRegex).936937#### `assertCountEqual(first, second, msg=None)`938939Проверяет, что последовательность *first* содержит те же элементы, что и *second*, независимо от их порядка. Если нет, генерируется сообщение об ошибке с перечислением различий между последовательностями.940941Дублирующиеся элементы *не* игнорируются при сравнении *first* и *second*. Проверяется, что каждый элемент встречается одинаковое количество раз в обеих последовательностях. Эквивалентно: `assertEqual(Counter(list(first)), Counter(list(second)))` но также работает с последовательностями нехешируемых объектов.942943Добавлено в версии 3.2.944945Метод [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual) направляет проверку равенства для объектов одного типа к различным методам, специфичным для типа. Эти методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощью [`addTypeEqualityFunc()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.addTypeEqualityFunc):946947#### `addTypeEqualityFunc(typeobj, function)`948949Регистрирует метод, специфичный для типа, вызываемый с помощью [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual) для проверки, равны ли два объекта одного и того же *typeobj* (не подклассы). *function* должен принимать два позиционных аргумента и третий именованный аргумент msg=None, как и [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual). Он должен вызывать [`self.failureException(msg)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.failureException) при обнаружении неравенства между первыми двумя параметрами – возможно, предоставляя полезную информацию и подробно объясняя неравенства в сообщении об ошибке.950951Добавлено в версии 3.1.952953Список типовых методов, автоматически используемых [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual), приведён в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать эти методы напрямую.954955| Метод | Используется для сравнения | Новое в |956| --- | --- | --- |957| [`assertMultiLineEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertMultiLineEqual) | строки | 3.1 |958| [`assertSequenceEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertSequenceEqual) | последовательности | 3.1 |959| [`assertListEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertListEqual) | списки | 3.1 |960| [`assertTupleEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertTupleEqual) | кортежи | 3.1 |961| [`assertSetEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertSetEqual) | множества или неизменяемые множества | 3.1 |962| [`assertDictEqual(a, b)`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertDictEqual) | словари | 3.1 |963964#### `assertMultiLineEqual(first, second, msg=None)`965966Проверяет, что многострочная строка *first* равна строке *second*. Если они не равны, в сообщение об ошибке включается diff двух строк с подсветкой различий. Этот метод используется по умолчанию при сравнении строк с помощью [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual).967968Добавлено в версии 3.1.969970#### `assertSequenceEqual(first, second, msg=None, seq_type=None)`971972Проверяет, что две последовательности равны. Если передан *seq\_type*, то *first* и *second* должны быть экземплярами *seq\_type*, иначе будет вызвана ошибка. Если последовательности различаются, формируется сообщение об ошибке, показывающее разницу между ними.973974Этот метод не вызывается напрямую методом [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual), но используется для реализации [`assertListEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertListEqual) и [`assertTupleEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertTupleEqual).975976Добавлено в версии 3.1.977978#### `assertListEqual(first, second, msg=None)`979980#### `assertTupleEqual(first, second, msg=None)`981982Проверяет, что два списка или кортежа равны. Если нет, формируется сообщение об ошибке, показывающее только различия между ними. Ошибка также возникает, если один из параметров имеет неверный тип. Эти методы используются по умолчанию при сравнении списков или кортежей с помощью [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual).983984Добавлено в версии 3.1.985986#### `assertSetEqual(first, second, msg=None)`987988Проверяет, что два множества равны. Если нет, формируется сообщение об ошибке, перечисляющее различия между множествами. Этот метод используется по умолчанию при сравнении множеств или неизменяемых множеств с помощью [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual).989990Завершается ошибкой, если *first* или *second* не имеет метода `set.difference()`.991992Добавлено в версии 3.1.993994#### `assertDictEqual(first, second, msg=None)`995996Проверяет, что два словаря равны. Если нет, формируется сообщение об ошибке, показывающее различия в словарях. Этот метод будет использоваться по умолчанию для сравнения словарей в вызовах [`assertEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertEqual).997998Добавлено в версии 3.1.9991000Наконец, [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) предоставляет следующие методы и атрибуты:10011002#### `fail(msg=None)`10031004Безусловно сигнализирует о сбое теста, используя *msg* или `None` в качестве сообщения об ошибке.10051006#### `failureException`10071008Этот атрибут класса задаёт исключение, которое вызывается тестовым методом. Если тестовому фреймворку требуется использовать специализированное исключение, возможно, для передачи дополнительной информации, он должен создать подкласс этого исключения, чтобы «честно играть» с фреймворком. Начальное значение этого атрибута – [`AssertionError`](https://python-all.ru/3.12/library/exceptions.html#AssertionError).10091010#### `longMessage`10111012Этот атрибут класса определяет, что происходит, когда пользовательское сообщение об ошибке передаётся в качестве аргумента msg в вызов assertXYY, который завершается сбоем. Значение по умолчанию – `True`. В этом случае пользовательское сообщение добавляется в конец стандартного сообщения об ошибке. Если установлено `False`, пользовательское сообщение заменяет стандартное.10131014Настройку класса можно переопределить в отдельных тестовых методах, присвоив атрибуту экземпляра self.longMessage значение `True` или `False` перед вызовом assert-методов.10151016Настройка класса сбрасывается перед каждым вызовом теста.10171018Добавлено в версии 3.1.10191020#### `maxDiff`10211022Этот атрибут управляет максимальной длиной вывода различий, выводимых методами утверждения, которые сообщают о различиях при неудаче. По умолчанию – 80\*8 символов. Методы утверждения, на которые влияет этот атрибут: [`assertSequenceEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertSequenceEqual) (включая все методы сравнения последовательностей, которые делегируют ему), [`assertDictEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertDictEqual) и [`assertMultiLineEqual()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.assertMultiLineEqual).10231024Установка `maxDiff` в `None` означает, что максимальная длина различий не ограничена.10251026Добавлено в версии 3.2.10271028Тестовые фреймворки могут использовать следующие методы для сбора информации о тесте:10291030#### `countTestCases()`10311032Возвращает количество тестов, представленных этим тестовым объектом. Для экземпляров [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) это всегда будет `1`.10331034#### `defaultTestResult()`10351036Возвращает экземпляр класса результата теста, который следует использовать для данного класса тестового случая (если ни один другой экземпляр результата не был передан методу [`run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.run)).10371038Для экземпляров [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) это всегда будет экземпляр [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult); подклассы [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) должны при необходимости переопределять это.10391040#### `id()`10411042Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя тестового метода, включая имя модуля и класса.10431044#### `shortDescription()`10451046Возвращает описание теста или `None`, если описание не было предоставлено. Реализация по умолчанию этого метода возвращает первую строку докстринга тестового метода, если он доступен, или `None`.10471048Изменено в версии 3.1: В 3.1 это было изменено, чтобы добавлять имя теста в краткое описание даже при наличии докстринга. Это вызвало проблемы совместимости с расширениями unittest, и добавление имени теста было перенесено в [`TextTestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TextTestResult) в Python 3.2.10491050#### `addCleanup(function, /, *args, **kwargs)`10511052Добавляет функцию, которая будет вызвана после [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown) для очистки ресурсов, использованных во время теста. Функции вызываются в порядке, обратном порядку их добавления (LIFO). Они вызываются с теми позиционными и именованными аргументами, которые были переданы в [`addCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.addCleanup) при их добавлении.10531054Если [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) завершается неудачей, то есть [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown) не вызывается, любые добавленные функции очистки всё равно будут вызваны.10551056Добавлено в версии 3.1.10571058#### `enterContext(cm)`10591060Входит в предоставленный [менеджер контекста](https://python-all.ru/3.12/glossary.html#term-context-manager). В случае успеха также добавляет его метод [`__exit__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__exit__) как функцию очистки с помощью [`addCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.addCleanup) и возвращает результат метода [`__enter__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__enter__).10611062Добавлено в версии 3.12.10631064#### `doCleanups()`10651066Этот метод вызывается безусловно после [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown) или после [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp), если [`setUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUp) вызывает исключение.10671068Он отвечает за вызов всех функций очистки, добавленных с помощью [`addCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.addCleanup). Если необходимо, чтобы функции очистки вызывались *до* [`tearDown()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDown), то можно вызвать [`doCleanups()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.doCleanups) самостоятельно.10691070[`doCleanups()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.doCleanups) извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любой момент.10711072Добавлено в версии 3.1.10731074#### `classmethod addClassCleanup(function, /, *args, **kwargs)`10751076Добавляет функцию, которая будет вызвана после [`tearDownClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDownClass) для очистки ресурсов, использованных во время тестового класса. Функции вызываются в обратном порядке по сравнению с порядком их добавления (LIFO). Они вызываются с теми аргументами и именованными аргументами, которые были переданы в [`addClassCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.addClassCleanup) при их добавлении.10771078Если [`setUpClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUpClass) завершается ошибкой, то есть [`tearDownClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDownClass) не вызывается, то все добавленные функции очистки всё равно будут вызваны.10791080Добавлено в версии 3.8.10811082#### `classmethod enterClassContext(cm)`10831084Входит в предоставленный [менеджер контекста](https://python-all.ru/3.12/glossary.html#term-context-manager). В случае успеха также добавляет его метод [`__exit__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__exit__) как функцию очистки с помощью [`addClassCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.addClassCleanup) и возвращает результат метода [`__enter__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__enter__).10851086Добавлено в версии 3.12.10871088#### `classmethod doClassCleanups()`10891090Этот метод вызывается безусловно после [`tearDownClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDownClass) или после [`setUpClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUpClass), если [`setUpClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.setUpClass) вызывает исключение.10911092Он отвечает за вызов всех функций очистки, добавленных с помощью [`addClassCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.addClassCleanup). Если нужно, чтобы функции очистки вызывались *до* [`tearDownClass()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.tearDownClass), то можно вызвать [`doClassCleanups()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.doClassCleanups) самостоятельно.10931094[`doClassCleanups()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.doClassCleanups) извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любой момент.10951096Добавлено в версии 3.8.10971098#### `class unittest.IsolatedAsyncioTestCase(methodName='runTest')`10991100Этот класс предоставляет API, похожий на [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), и также принимает корутины в качестве тестовых функций.11011102Добавлено в версии 3.8.11031104#### `async asyncSetUp()`11051106Метод вызывается для подготовки тестового окружения. Он вызывается после `setUp()`, непосредственно перед вызовом тестового метода; любое исключение, возбуждённое этим методом, за исключением [`AssertionError`](https://python-all.ru/3.12/library/exceptions.html#AssertionError) или [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest), считается ошибкой, а не неудачей теста. Реализация по умолчанию ничего не делает.11071108#### `async asyncTearDown()`11091110Метод, вызываемый сразу после вызова тестового метода и записи результата. Вызывается перед `tearDown()`. Вызывается даже если тестовый метод возбудил исключение, поэтому реализация в подклассах должна быть особенно осторожна при проверке внутреннего состояния. Любое исключение, возбуждённое этим методом, за исключением [`AssertionError`](https://python-all.ru/3.12/library/exceptions.html#AssertionError) или [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest), считается дополнительной ошибкой, а не неудачей теста (таким образом, увеличивая общее количество сообщённых ошибок). Этот метод вызывается только в случае успеха [`asyncSetUp()`](https://python-all.ru/3.12/library/unittest.html#unittest.IsolatedAsyncioTestCase.asyncSetUp), независимо от результата тестового метода. Реализация по умолчанию ничего не делает.11111112#### `addAsyncCleanup(function, /, *args, **kwargs)`11131114Этот метод принимает корутину, которая может использоваться как функция очистки.11151116#### `async enterAsyncContext(cm)`11171118Входит в предоставленный [асинхронный менеджер контекста](https://python-all.ru/3.12/glossary.html#term-asynchronous-context-manager). В случае успеха также добавляет его метод [`__aexit__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__aexit__) как функцию очистки с помощью [`addAsyncCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.IsolatedAsyncioTestCase.addAsyncCleanup) и возвращает результат метода [`__aenter__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__aenter__).11191120Добавлено в версии 3.12.11211122#### `run(result=None)`11231124Настраивает новый цикл событий для выполнения теста, собирая результат в объект [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult), переданный как *result*. Если *result* опущен или равен `None`, создаётся временный объект результата (вызовом метода `defaultTestResult()`) и используется. Объект результата возвращается вызывающему [`run()`](https://python-all.ru/3.12/library/unittest.html#unittest.IsolatedAsyncioTestCase.run). В конце теста все задачи в цикле событий отменяются.11251126Пример, иллюстрирующий порядок:11271128```python1129from unittest import IsolatedAsyncioTestCase11301131events = []11321133class Test(IsolatedAsyncioTestCase):11341135 def setUp(self):1136 events.append("setUp")11371138 async def asyncSetUp(self):1139 self._async_connection = await AsyncConnection()1140 events.append("asyncSetUp")11411142 async def test_response(self):1143 events.append("test_response")1144 response = await self._async_connection.get("https://example.com")1145 self.assertEqual(response.status_code, 200)1146 self.addAsyncCleanup(self.on_cleanup)11471148 def tearDown(self):1149 events.append("tearDown")11501151 async def asyncTearDown(self):1152 await self._async_connection.close()1153 events.append("asyncTearDown")11541155 async def on_cleanup(self):1156 events.append("cleanup")11571158if __name__ == "__main__":1159 unittest.main()1160```11611162После запуска теста `events` будет содержать `["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]`.11631164#### `class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)`11651166Этот класс реализует ту часть интерфейса [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), которая позволяет исполнителю тестов управлять тестом, но не предоставляет методов, которые тестовый код может использовать для проверки и сообщения об ошибках. Это используется для создания тестовых примеров с использованием устаревшего тестового кода, что позволяет интегрировать его в тестовую среду на основе [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest).11671168### Группировка тестов11691170#### `class unittest.TestSuite(tests=())`11711172Этот класс представляет собой агрегацию отдельных тестовых примеров и тестовых наборов. Класс предоставляет интерфейс, необходимый исполнителю тестов, чтобы его можно было запускать как любой другой тестовый пример. Запуск экземпляра [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) равносилен итерации по набору с запуском каждого теста по отдельности.11731174Если задан *tests*, он должен быть итерабельным объектом, содержащим отдельные тестовые примеры или другие тестовые наборы, которые будут использоваться для первоначального построения набора. Дополнительные методы предоставляются для добавления тестовых примеров и наборов в коллекцию позже.11751176Объекты [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) ведут себя во многом как объекты [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), за исключением того, что они не реализуют фактический тест. Вместо этого они используются для объединения тестов в группы, которые должны запускаться вместе. Некоторые дополнительные методы доступны для добавления тестов в экземпляры [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite):11771178#### `addTest(test)`11791180Добавляет [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) в набор.11811182#### `addTests(tests)`11831184Добавляет все тесты из итерабельного объекта, содержащего экземпляры [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) и [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite), в этот тестовый набор.11851186Это эквивалентно итерации по *tests* с вызовом [`addTest()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite.addTest) для каждого элемента.11871188[`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) разделяет следующие методы с [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase):11891190#### `run(result)`11911192Запускает тесты, связанные с этим набором, собирая результат в объект результата теста, переданный как *result*. Обратите внимание, что, в отличие от [`TestCase.run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase.run), [`TestSuite.run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite.run) требует, чтобы объект результата был передан.11931194#### `debug()`11951196Запускает тесты, связанные с этим набором, без сбора результата. Это позволяет исключениям, возбуждённым тестом, распространяться до вызывающего кода и может использоваться для поддержки запуска тестов под отладчиком.11971198#### `countTestCases()`11991200Возвращает количество тестов, представленных этим тестовым объектом, включая все отдельные тесты и поднаборы.12011202#### `__iter__()`12031204Тесты, сгруппированные с помощью [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite), всегда доступны через итерацию. Подклассы могут лениво предоставлять тесты, переопределяя `__iter__()`. Обратите внимание, что этот метод может вызываться несколько раз для одного набора (например, при подсчёте тестов или сравнении на равенство), поэтому тесты, возвращаемые повторными итерациями до [`TestSuite.run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite.run), должны быть одинаковыми для каждого вызова итерации. После [`TestSuite.run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite.run) вызывающий код не должен полагаться на тесты, возвращаемые этим методом, если только вызывающий код не использует подкласс, который переопределяет `TestSuite._removeTestAtIndex()` для сохранения ссылок на тесты.12051206Изменено в версии 3.2: В более ранних версиях [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) обращался к тестам напрямую, а не через итерацию, поэтому переопределения `__iter__()` было недостаточно для предоставления тестов.12071208Изменено в версии 3.4: В более ранних версиях [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) хранил ссылки на каждый [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) после [`TestSuite.run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite.run). Подклассы могут восстановить такое поведение, переопределив `TestSuite._removeTestAtIndex()`.12091210При типичном использовании объекта [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) метод [`run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite.run) вызывается с помощью `TestRunner`, а не через тестовую оболочку конечного пользователя.12111212### Загрузка и запуск тестов12131214#### `class unittest.TestLoader`12151216Класс [`TestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader) используется для создания тестовых наборов из классов и модулей. Обычно нет необходимости создавать экземпляр этого класса; модуль [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest) предоставляет экземпляр, который можно использовать совместно как [`unittest.defaultTestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.defaultTestLoader). Однако использование подкласса или экземпляра позволяет настраивать некоторые конфигурируемые свойства.12171218Объекты [`TestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader) имеют следующие атрибуты:12191220#### `errors`12211222Список нефатальных ошибок, возникших при загрузке тестов. Не сбрасывается загрузчиком ни в какой момент. Фатальные ошибки сигнализируются соответствующим методом, который генерирует исключение для вызывающего кода. Нефатальные ошибки также указываются синтетическим тестом, который при выполнении вызовет исходную ошибку.12231224Добавлено в версии 3.5.12251226Объекты [`TestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader) имеют следующие методы:12271228#### `loadTestsFromTestCase(testCaseClass)`12291230Возвращает набор всех тестов, содержащихся в `testCaseClass`, производном от [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase).12311232Экземпляр тестового случая создаётся для каждого метода, именованного [`getTestCaseNames()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader.getTestCaseNames). По умолчанию это имена методов, начинающиеся с `test`. Если [`getTestCaseNames()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader.getTestCaseNames) не возвращает ни одного метода, но метод `runTest()` реализован, то вместо этого создаётся один тестовый случай для этого метода.12331234#### `loadTestsFromModule(module, *, pattern=None)`12351236Возвращает набор всех тестовых случаев, содержащихся в данном модуле. Этот метод ищет в *module* классы, производные от [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), и создаёт экземпляр класса для каждого тестового метода, определённого для этого класса.12371238> **Примечание**1239>1240> Хотя использование иерархии классов, производных от [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), может быть удобным для совместного использования фикстур и вспомогательных функций, определение тестовых методов в базовых классах, которые не предназначены для прямого создания экземпляров, плохо сочетается с этим методом. Однако это может быть полезно, когда фикстуры различаются и определены в подклассах.12411242Если модуль предоставляет функцию `load_tests`, она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это называется [протокол load\_tests](https://python-all.ru/3.12/library/unittest.html#id1). Аргумент *pattern* передаётся как третий аргумент в `load_tests`.12431244Изменено в версии 3.2: Добавлена поддержка `load_tests`.12451246Изменено в версии 3.5: Добавлена поддержка аргумента, передаваемого только по ключу, *pattern*.12471248Изменено в версии 3.12: Незадокументированный и неофициальный параметр *use\_load\_tests* был удалён.12491250#### `loadTestsFromName(name, module=None)`12511252Возвращает набор всех тестовых случаев по заданному строковому спецификатору.12531254Спецификатор *name* – это «точечное имя», которое может указывать на модуль, класс тестового случая, тестовый метод внутри класса тестового случая, экземпляр [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) или вызываемый объект, возвращающий экземпляр [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite). Эти проверки применяются в указанном порядке; то есть метод в возможном классе тестового случая будет распознан как «тестовый метод внутри класса тестового случая», а не как «вызываемый объект».12551256Например, если у вас есть модуль `SampleTests`, содержащий класс `SampleTestCase`, производный от [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), с тремя тестовыми методами (`test_one()`, `test_two()` и `test_three()`), спецификатор `'SampleTests.SampleTestCase'` заставит этот метод вернуть набор, который выполнит все три тестовых метода. Использование спецификатора `'SampleTests.SampleTestCase.test_two'` приведёт к возврату тестового набора, который выполнит только тестовый метод `test_two()`. Спецификатор может ссылаться на модули и пакеты, которые не были импортированы; они будут импортированы как побочный эффект.12571258Метод опционально разрешает *name* относительно заданного *module*.12591260Изменено в версии 3.5: Если при обходе *name* возникает [`ImportError`](https://python-all.ru/3.12/library/exceptions.html#ImportError) или [`AttributeError`](https://python-all.ru/3.12/library/exceptions.html#AttributeError), то будет возвращён синтетический тест, который при выполнении вызывает эту ошибку. Эти ошибки включаются в ошибки, накопленные self.errors.12611262#### `loadTestsFromNames(names, module=None)`12631264Аналогичен [`loadTestsFromName()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader.loadTestsFromName), но принимает последовательность имён, а не одно имя. Возвращаемое значение – тестовый набор, который включает все тесты, определённые для каждого имени.12651266#### `getTestCaseNames(testCaseClass)`12671268Возвращает отсортированную последовательность имён методов, найденных в *testCaseClass*; это должен быть подкласс [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase).12691270#### `discover(start_dir, pattern='test*.py', top_level_dir=None)`12711272Находит все тестовые модули, рекурсивно обходя подкаталоги, начиная с указанного каталога, и возвращает объект TestSuite, содержащий их. Будут загружены только тестовые файлы, соответствующие *pattern*. (Используется сопоставление с образцом в стиле shell.) Будут загружены только имена модулей, которые можно импортировать (т.е. являются допустимыми идентификаторами Python).12731274Все тестовые модули должны быть импортируемы из корневого каталога проекта. Если начальный каталог не является корневым, то *top\_level\_dir* необходимо указать отдельно.12751276Если импорт модуля завершается неудачей, например из-за синтаксической ошибки, это записывается как одна ошибка, и поиск продолжается. Если неудача импорта связана с возникновением [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest), это будет записано как пропуск, а не как ошибка.12771278Если найден пакет (каталог, содержащий файл с именем `__init__.py`), в пакете проверяется наличие функции `load_tests`. Если она существует, она вызывается с помощью `package.load_tests(loader, tests, pattern)`. Поиск тестов гарантирует, что пакет проверяется на наличие тестов только один раз за вызов, даже если сама функция load\_tests вызывает `loader.discover`.12791280Если `load_tests` существует, то поиск *не* рекурсирует в пакет, `load_tests` отвечает за загрузку всех тестов в пакете.12811282Шаблон намеренно не хранится как атрибут загрузчика, чтобы пакеты могли продолжать поиск самостоятельно.12831284*top\_level\_dir* хранится внутренне и используется по умолчанию для любых вложенных вызовов `discover()`. То есть, если `load_tests` пакета вызывает `loader.discover()`, ему не нужно передавать этот аргумент.12851286*start\_dir* может быть как точечным именем модуля, так и каталогом.12871288Добавлено в версии 3.2.12891290Изменено в версии 3.4: Модули, вызывающие [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest) при импорте, записываются как пропуски, а не ошибки.12911292Изменено в версии 3.4: *start\_dir* может быть [пакетом пространства имён](https://python-all.ru/3.12/glossary.html#term-namespace-package).12931294Изменено в версии 3.4: Пути сортируются перед импортом, так что порядок выполнения остаётся одинаковым, даже если порядок, задаваемый файловой системой, не зависит от имени файла.12951296Изменено в версии 3.5: Найденные пакеты теперь проверяются на наличие `load_tests` независимо от того, соответствует ли их путь *pattern*, поскольку имя пакета не может соответствовать шаблону по умолчанию.12971298Изменено в версии 3.11: *start\_dir* не может быть [пакетом пространства имён](https://python-all.ru/3.12/glossary.html#term-namespace-package). Это поведение было нарушено начиная с Python 3.7, и Python 3.11 официально удаляет его.12991300Изменено в версии 3.12.4: *top\_level\_dir* сохраняется только на время вызова *discover*13011302Следующие атрибуты [`TestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader) можно настроить либо через наследование, либо через присваивание экземпляру:13031304#### `testMethodPrefix`13051306Строка, задающая префикс имён методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию – `'test'`.13071308Это влияет на [`getTestCaseNames()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader.getTestCaseNames) и все методы `loadTestsFrom*`.13091310#### `sortTestMethodsUsing`13111312Функция, используемая для сравнения имён методов при их сортировке в [`getTestCaseNames()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader.getTestCaseNames) и во всех методах `loadTestsFrom*`.13131314#### `suiteClass`13151316Вызываемый объект, который создаёт тестовый набор из списка тестов. Никакие методы результирующего объекта не требуются. Значение по умолчанию – класс [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite).13171318Это влияет на все методы `loadTestsFrom*`.13191320#### `testNamePatterns`13211322Список шаблонов имён тестов в стиле оболочки Unix (символы подстановки), которым должны соответствовать тестовые методы для включения в наборы тестов (см. опцию `-k`).13231324Если этот атрибут не равен `None` (по умолчанию), все тестовые методы, которые должны быть включены в тестовые наборы, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что сопоставление всегда выполняется с помощью [`fnmatch.fnmatchcase()`](https://python-all.ru/3.12/library/fnmatch.html#fnmatch.fnmatchcase), поэтому, в отличие от шаблонов, переданных опции `-k`, простые шаблоны подстрок придётся преобразовать с использованием подстановочных знаков `*`.13251326Это влияет на все методы `loadTestsFrom*`.13271328Добавлено в версии 3.7.13291330#### `class unittest.TestResult`13311332Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие завершились неудачей.13331334Объект [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult) хранит результаты набора тестов. Классы [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) и [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) обеспечивают правильную запись результатов; авторам тестов не нужно беспокоиться о записи результатов тестов.13351336Тестовые фреймворки, построенные на базе [`unittest`](https://python-all.ru/3.12/library/unittest.html#module-unittest), могут нуждаться в доступе к объекту [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult), созданному при запуске набора тестов для целей отчетности; для этого метод `TestRunner.run()` возвращает экземпляр [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult).13371338Экземпляры [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult) имеют следующие атрибуты, которые будут интересны при проверке результатов запуска набора тестов:13391340#### `errors`13411342Список, содержащий 2-кортежи экземпляров [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) и строк с форматированными трассировками. Каждый кортеж представляет тест, вызвавший неожиданное исключение.13431344#### `failures`13451346Список, содержащий 2-кортежи экземпляров [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) и строк с форматированными трассировками. Каждый кортеж представляет тест, в котором сбой был явно обозначен с помощью методов [assert\*](https://python-all.ru/3.12/library/unittest.html#assert-methods).13471348#### `skipped`13491350Список, содержащий 2-кортежи экземпляров [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) и строк с причиной пропуска теста.13511352Добавлено в версии 3.1.13531354#### `expectedFailures`13551356Список, содержащий 2-кортежи экземпляров [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) и строк с форматированными трассировками. Каждый кортеж представляет ожидаемый сбой или ошибку тестового случая.13571358#### `unexpectedSuccesses`13591360Список, содержащий экземпляры [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), которые были помечены как ожидаемые сбои, но завершились успешно.13611362#### `collectedDurations`13631364Список, содержащий 2-кортежи имен тестовых случаев и чисел с плавающей точкой, представляющих затраченное время каждого запущенного теста.13651366Добавлено в версии 3.12.13671368#### `shouldStop`13691370Устанавливается в `True`, когда выполнение тестов должно быть остановлено с помощью [`stop()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.stop).13711372#### `testsRun`13731374Общее количество запущенных на данный момент тестов.13751376#### `buffer`13771378Если установлено в true, `sys.stdout` и `sys.stderr` будут буферизироваться между вызовами [`startTest()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.startTest) и [`stopTest()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.stopTest). Собранный вывод будет передаваться на реальные `sys.stdout` и `sys.stderr` только в случае сбоя или ошибки теста. Любой вывод также прикрепляется к сообщению о сбое/ошибке.13791380Добавлено в версии 3.2.13811382#### `failfast`13831384Если установлено в true, [`stop()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.stop) будет вызван при первой ошибке или сбое, останавливая выполнение теста.13851386Добавлено в версии 3.2.13871388#### `tb_locals`13891390Если установлено в true, то локальные переменные будут отображаться в трассировках.13911392Добавлено в версии 3.5.13931394#### `wasSuccessful()`13951396Возвращает `True`, если все запущенные на данный момент тесты пройдены, в противном случае возвращает `False`.13971398Изменено в версии 3.4: Возвращает `False`, если были какие-либо [`unexpectedSuccesses`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.unexpectedSuccesses) от тестов, помеченных декоратором [`expectedFailure()`](https://python-all.ru/3.12/library/unittest.html#unittest.expectedFailure).13991400#### `stop()`14011402Этот метод может быть вызван, чтобы указать, что выполняемый набор тестов должен быть прерван установкой атрибута [`shouldStop`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.shouldStop) в `True`. Объекты `TestRunner` должны учитывать этот флаг и возвращаться без запуска дополнительных тестов.14031404Например, эта возможность используется классом [`TextTestRunner`](https://python-all.ru/3.12/library/unittest.html#unittest.TextTestRunner) для остановки тестового фреймворка, когда пользователь подает сигнал прерывания с клавиатуры. Интерактивные инструменты, предоставляющие реализации `TestRunner`, могут использовать это аналогичным образом.14051406Следующие методы класса [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult) используются для поддержки внутренних структур данных и могут быть расширены в подклассах для поддержки дополнительных требований к отчетности. Это особенно полезно при создании инструментов, поддерживающих интерактивную отчетность во время выполнения тестов.14071408#### `startTest(test)`14091410Вызывается перед запуском тестового сценария *test*.14111412#### `stopTest(test)`14131414Вызывается после выполнения тестового сценария *test*, независимо от результата.14151416#### `startTestRun()`14171418Вызывается один раз перед выполнением любых тестов.14191420Добавлено в версии 3.1.14211422#### `stopTestRun()`14231424Вызывается один раз после выполнения всех тестов.14251426Добавлено в версии 3.1.14271428#### `addError(test, err)`14291430Вызывается, когда тестовый сценарий *test* порождает неожиданное исключение. *err* – кортеж вида, возвращаемого [`sys.exc_info()`](https://python-all.ru/3.12/library/sys.html#sys.exc_info): `(type, value, traceback)`.14311432Реализация по умолчанию добавляет кортеж `(test, formatted_err)` к атрибуту [`errors`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.errors) экземпляра, где *formatted\_err* – форматированная трассировка, полученная из *err*.14331434#### `addFailure(test, err)`14351436Вызывается, когда тестовый сценарий *test* сигнализирует о сбое. *err* – кортеж вида, возвращаемого [`sys.exc_info()`](https://python-all.ru/3.12/library/sys.html#sys.exc_info): `(type, value, traceback)`.14371438Реализация по умолчанию добавляет кортеж `(test, formatted_err)` к атрибуту [`failures`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.failures) экземпляра, где *formatted\_err* – форматированная трассировка, полученная из *err*.14391440#### `addSuccess(test)`14411442Вызывается, когда тестовый сценарий *test* завершается успешно.14431444Реализация по умолчанию ничего не делает.14451446#### `addSkip(test, reason)`14471448Вызывается, когда тестовый сценарий *test* пропускается. *reason* – причина, которую тест указал для пропуска.14491450Реализация по умолчанию добавляет кортеж `(test, reason)` к атрибуту [`skipped`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.skipped) экземпляра.14511452#### `addExpectedFailure(test, err)`14531454Вызывается, когда тестовый сценарий *test* завершается неудачей или ошибкой, но был помечен декоратором [`expectedFailure()`](https://python-all.ru/3.12/library/unittest.html#unittest.expectedFailure).14551456Реализация по умолчанию добавляет кортеж `(test, formatted_err)` к атрибуту [`expectedFailures`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.expectedFailures) экземпляра, где *formatted\_err* – форматированная трассировка, полученная из *err*.14571458#### `addUnexpectedSuccess(test)`14591460Вызывается, когда тестовый сценарий *test* был помечен декоратором [`expectedFailure()`](https://python-all.ru/3.12/library/unittest.html#unittest.expectedFailure), но завершился успешно.14611462Реализация по умолчанию добавляет тест к атрибуту [`unexpectedSuccesses`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.unexpectedSuccesses) экземпляра.14631464#### `addSubTest(test, subtest, outcome)`14651466Вызывается, когда завершается подтест. *test* – тестовый сценарий, соответствующий тестовому методу. *subtest* – пользовательский экземпляр [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), описывающий подтест.14671468Если *outcome* равен [`None`](https://python-all.ru/3.12/library/constants.html#None), подтест завершился успешно. В противном случае он завершился исключением, где *outcome* – кортеж вида, возвращаемого [`sys.exc_info()`](https://python-all.ru/3.12/library/sys.html#sys.exc_info): `(type, value, traceback)`.14691470Реализация по умолчанию ничего не делает, если результат – успех, и записывает сбои подтестов как обычные сбои.14711472Добавлено в версии 3.4.14731474#### `addDuration(test, elapsed)`14751476Вызывается после завершения тестового сценария. *elapsed* – время, выраженное в секундах, включающее выполнение функций очистки.14771478Добавлено в версии 3.12.14791480#### `class unittest.TextTestResult(stream, descriptions, verbosity, *, durations=None)`14811482Конкретная реализация [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult), используемая [`TextTestRunner`](https://python-all.ru/3.12/library/unittest.html#unittest.TextTestRunner). Подклассы должны принимать `**kwargs`, чтобы обеспечить совместимость при изменении интерфейса.14831484Добавлено в версии 3.2.14851486Изменено в версии 3.12: Добавлен именованный параметр *durations*.14871488#### `unittest.defaultTestLoader`14891490Экземпляр класса [`TestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader), предназначенный для совместного использования. Если настройка [`TestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader) не требуется, можно использовать этот экземпляр вместо повторного создания новых.14911492#### `class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False, durations=None)`14931494Базовая реализация запуска тестов, которая выводит результаты в поток данных. Если *stream* равен `None` (значение по умолчанию), в качестве выходного потока данных используется [`sys.stderr`](https://python-all.ru/3.12/library/sys.html#sys.stderr). Этот класс имеет несколько настраиваемых параметров, но в целом очень прост. Графические приложения, запускающие наборы тестов, должны предоставлять альтернативные реализации. Такие реализации должны принимать `**kwargs`, поскольку интерфейс для создания запускаторов меняется при добавлении новых возможностей в unittest.14951496По умолчанию этот запускатор показывает [`DeprecationWarning`](https://python-all.ru/3.12/library/exceptions.html#DeprecationWarning), [`PendingDeprecationWarning`](https://python-all.ru/3.12/library/exceptions.html#PendingDeprecationWarning), [`ResourceWarning`](https://python-all.ru/3.12/library/exceptions.html#ResourceWarning) и [`ImportWarning`](https://python-all.ru/3.12/library/exceptions.html#ImportWarning), даже если они [игнорируются по умолчанию](https://python-all.ru/3.12/library/warnings.html#warning-ignored). Это поведение можно переопределить с помощью опций Python `-Wd` или `-Wa` (см. [Управление предупреждениями](https://python-all.ru/3.12/using/cmdline.html#using-on-warnings)), оставив *warnings* равным `None`.14971498Изменено в версии 3.2: Добавлен параметр *warnings*.14991500Изменено в версии 3.2: Поток по умолчанию устанавливается на [`sys.stderr`](https://python-all.ru/3.12/library/sys.html#sys.stderr) в момент создания экземпляра, а не при импорте.15011502Изменено в версии 3.5: Добавлен параметр *tb\_locals*.15031504Изменено в версии 3.12: Добавлен параметр *durations*.15051506#### `_makeResult()`15071508Этот метод возвращает экземпляр `TestResult`, используемый [`run()`](https://python-all.ru/3.12/library/unittest.html#unittest.TextTestRunner.run). Он не предназначен для прямого вызова, но может быть переопределён в подклассах для предоставления собственного `TestResult`.15091510`_makeResult()` создаёт экземпляр класса или вызываемого объекта, переданного в конструктор `TextTestRunner` как аргумент `resultclass`. По умолчанию используется [`TextTestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TextTestResult), если `resultclass` не предоставлен. Класс результата создаётся со следующими аргументами:15111512```python1513stream, descriptions, verbosity1514```15151516#### `run(test)`15171518Этот метод является основным публичным интерфейсом `TextTestRunner`. Он принимает экземпляр [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite) или [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase). [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult) создаётся вызовом [`_makeResult()`](https://python-all.ru/3.12/library/unittest.html#unittest.TextTestRunner._makeResult), после чего тест(ы) выполняются, а результаты выводятся в stdout.15191520#### `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)`15211522Программа командной строки, которая загружает набор тестов из *module* и запускает их; это в первую очередь для удобного выполнения тестовых модулей. Простейший способ использования этой функции – добавить следующую строку в конец тестового скрипта:15231524```python1525if __name__ == '__main__':1526 unittest.main()1527```15281529Можно запускать тесты с более подробной информацией, передав аргумент verbosity:15301531```python1532if __name__ == '__main__':1533 unittest.main(verbosity=2)1534```15351536Аргумент *defaultTest* может быть либо именем одного теста, либо итерируемым объектом с именами тестов для запуска, если имена тестов не указаны через *argv*. Если он не задан или равен `None`, а имена тестов не переданы через *argv*, выполняются все тесты, найденные в *module*.15371538Аргумент *argv* может быть списком параметров, переданных программе, где первый элемент – имя программы. Если он не задан или равен `None`, используются значения [`sys.argv`](https://python-all.ru/3.12/library/sys.html#sys.argv).15391540Аргумент *testRunner* может быть либо классом запускатора тестов, либо уже созданным экземпляром такого класса. По умолчанию `main` вызывает [`sys.exit()`](https://python-all.ru/3.12/library/sys.html#sys.exit) с кодом возврата, указывающим на успех (0) или неудачу (1) выполненных тестов. Код возврата 5 означает, что тесты не выполнялись или были пропущены.15411542Аргумент *testLoader* должен быть экземпляром [`TestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader) и по умолчанию равен [`defaultTestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.defaultTestLoader).15431544`main` поддерживает использование из интерактивного интерпретатора при передаче аргумента `exit=False`. При этом результат выводится в стандартный вывод без вызова [`sys.exit()`](https://python-all.ru/3.12/library/sys.html#sys.exit):15451546```python1547>>> from unittest import main1548>>> main(module='test_module', exit=False)1549```15501551Параметры *failfast*, *catchbreak* и *buffer* имеют тот же эффект, что и одноимённые [параметры командной строки](https://python-all.ru/3.12/library/unittest.html#command-line-options).15521553Аргумент *warnings* задаёт [фильтр предупреждений](https://python-all.ru/3.12/library/warnings.html#warning-filter), который следует использовать при выполнении тестов. Если он не указан, он останется `None` при передаче опции `-W` в **python** (см. [Управление предупреждениями](https://python-all.ru/3.12/using/cmdline.html#using-on-warnings)), в противном случае будет установлен в `'default'`.15541555Вызов `main` возвращает объект с атрибутом `result`, содержащим результат выполнения тестов в виде [`unittest.TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult).15561557Изменено в версии 3.1: Добавлен параметр *exit*.15581559Изменено в версии 3.2: Добавлены параметры *verbosity*, *failfast*, *catchbreak*, *buffer* и *warnings*.15601561Изменено в версии 3.4: Параметр *defaultTest* был изменён: теперь он также принимает итерируемый объект с именами тестов.15621563#### Протокол load\_tests15641565Добавлено в версии 3.2.15661567Модули или пакеты могут настраивать загрузку тестов из себя во время обычного запуска тестов или их обнаружения, реализуя функцию с именем `load_tests`.15681569Если тестовый модуль определяет `load_tests`, то он будет вызван функцией [`TestLoader.loadTestsFromModule()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader.loadTestsFromModule) со следующими аргументами:15701571```python1572load_tests(loader, standard_tests, pattern)1573```15741575где *pattern* передаётся напрямую из `loadTestsFromModule`. По умолчанию он равен `None`.15761577Она должна возвращать объект [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite).15781579*loader* – это экземпляр [`TestLoader`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader), выполняющий загрузку. *standard\_tests* – это тесты, которые будут загружены по умолчанию из модуля. Часто тестовые модули хотят только добавить или удалить тесты из стандартного набора. Третий аргумент используется при загрузке пакетов в рамках обнаружения тестов.15801581Типичная функция `load_tests`, загружающая тесты из определённого набора классов [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase), может выглядеть так:15821583```python1584test_cases = (TestCase1, TestCase2, TestCase3)15851586def load_tests(loader, tests, pattern):1587 suite = TestSuite()1588 for test_class in test_cases:1589 tests = loader.loadTestsFromTestCase(test_class)1590 suite.addTests(tests)1591 return suite1592```15931594Если обнаружение запускается в каталоге, содержащем пакет, либо из командной строки, либо вызовом [`TestLoader.discover()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestLoader.discover), то у пакета `__init__.py` проверяется наличие `load_tests`. Если такой функции нет, обнаружение рекурсивно обходит пакет, как если бы это был просто ещё один каталог. В противном случае обнаружение тестов пакета передаётся функции `load_tests`, которая вызывается со следующими аргументами:15951596```python1597load_tests(loader, standard_tests, pattern)1598```15991600Она должна возвращать объект [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite), представляющий все тесты из пакета. (`standard_tests` будет содержать только тесты, собранные из `__init__.py`.)16011602Поскольку шаблон передаётся в `load_tests`, пакет может продолжить (и, возможно, изменить) обнаружение тестов. Функция `load_tests`, которая ничего не делает, для тестового пакета может выглядеть так:16031604```python1605def load_tests(loader, standard_tests, pattern):1606 # корневой каталог, кэшированный на экземпляре загрузчика1607 this_dir = os.path.dirname(__file__)1608 package_tests = loader.discover(start_dir=this_dir, pattern=pattern)1609 standard_tests.addTests(package_tests)1610 return standard_tests1611```16121613Изменено в версии 3.5: Обнаружение больше не проверяет имена пакетов на соответствие *pattern* из-за невозможности соответствия имён пакетов шаблону по умолчанию.16141615## Фикстуры классов и модулей16161617Фикстуры уровня класса и модуля реализуются в [`TestSuite`](https://python-all.ru/3.12/library/unittest.html#unittest.TestSuite). Когда набор тестов встречает тест из нового класса, вызывается `tearDownClass()` из предыдущего класса (если он есть), а затем `setUpClass()` из нового класса.16181619Аналогично, если тест из другого модуля, отличного от предыдущего, то запускается `tearDownModule` предыдущего модуля, а затем `setUpModule` нового модуля.16201621После выполнения всех тестов запускаются финальные `tearDownClass` и `tearDownModule`.16221623Обратите внимание, что общие фикстуры плохо совместимы с такими возможностями, как параллельное выполнение тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.16241625Упорядочивание тестов по умолчанию, создаваемое загрузчиками тестов unittest, группирует все тесты из одних и тех же модулей и классов вместе. Это приводит к тому, что `setUpClass` / `setUpModule` (и т.д.) вызываются ровно один раз на класс и модуль. Если изменить порядок случайным образом, так что тесты из разных модулей и классов будут соседствовать друг с другом, то эти общие фикстуры могут вызываться несколько раз за один прогон тестов.16261627Общие фикстуры не предназначены для работы с наборами тестов, имеющими нестандартный порядок. `BaseTestSuite` всё ещё существует для фреймворков, которые не хотят поддерживать общие фикстуры.16281629Если во время выполнения одной из общих фикстур возникает исключение, тест помечается как ошибочный. Поскольку нет соответствующего экземпляра теста, создаётся объект `_ErrorHolder` (имеющий тот же интерфейс, что и [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase)) для представления ошибки. Если вы просто используете стандартный исполнитель тестов unittest, эта деталь не имеет значения, но если вы разработчик фреймворка, это может быть актуально.16301631### setUpClass и tearDownClass16321633Они должны быть реализованы как методы класса:16341635```python1636import unittest16371638class Test(unittest.TestCase):1639 @classmethod1640 def setUpClass(cls):1641 cls._connection = createExpensiveConnectionObject()16421643 @classmethod1644 def tearDownClass(cls):1645 cls._connection.destroy()1646```16471648Если нужно, чтобы `setUpClass` и `tearDownClass` базовых классов вызывались, необходимо вызвать их самостоятельно. Реализации в [`TestCase`](https://python-all.ru/3.12/library/unittest.html#unittest.TestCase) пусты.16491650Если во время выполнения `setUpClass` возникает исключение, тесты в классе не запускаются, и `tearDownClass` не выполняется. Пропущенные классы не будут выполнять `setUpClass` или `tearDownClass`. Если исключением является [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest), то класс будет помечен как пропущенный, а не как ошибочный.16511652### setUpModule и tearDownModule16531654Их следует реализовывать как функции:16551656```python1657def setUpModule():1658 createConnection()16591660def tearDownModule():1661 closeConnection()1662```16631664Если в `setUpModule` возникает исключение, то ни один тест в модуле не будет запущен, и `tearDownModule` не будет выполнен. Если исключением является [`SkipTest`](https://python-all.ru/3.12/library/unittest.html#unittest.SkipTest), то модуль будет помечен как пропущенный, а не как ошибочный.16651666Чтобы добавить код очистки, который должен выполняться даже в случае исключения, используйте `addModuleCleanup`:16671668#### `unittest.addModuleCleanup(function, /, *args, **kwargs)`16691670Добавляет функцию, которая будет вызвана после `tearDownModule()` для очистки ресурсов, использованных во время тестового класса. Функции вызываются в обратном порядке по сравнению с порядком их добавления (LIFO). Они вызываются с теми аргументами и именованными аргументами, которые были переданы в [`addModuleCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.addModuleCleanup) при их добавлении.16711672Если `setUpModule()` завершается ошибкой, то есть `tearDownModule()` не вызывается, то все добавленные функции очистки всё равно будут вызваны.16731674Добавлено в версии 3.8.16751676#### `classmethod unittest.enterModuleContext(cm)`16771678Входит в предоставленный [менеджер контекста](https://python-all.ru/3.12/glossary.html#term-context-manager). В случае успеха также добавляет его метод [`__exit__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__exit__) как функцию очистки с помощью [`addModuleCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.addModuleCleanup) и возвращает результат метода [`__enter__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__enter__).16791680Добавлено в версии 3.12.16811682#### `unittest.doModuleCleanups()`16831684Эта функция вызывается безусловно после `tearDownModule()` или после `setUpModule()`, если `setUpModule()` вызывает исключение.16851686Он отвечает за вызов всех функций очистки, добавленных с помощью [`addModuleCleanup()`](https://python-all.ru/3.12/library/unittest.html#unittest.addModuleCleanup). Если нужно, чтобы функции очистки вызывались *до* `tearDownModule()`, то можно вызвать [`doModuleCleanups()`](https://python-all.ru/3.12/library/unittest.html#unittest.doModuleCleanups) самостоятельно.16871688[`doModuleCleanups()`](https://python-all.ru/3.12/library/unittest.html#unittest.doModuleCleanups) извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любой момент.16891690Добавлено в версии 3.8.16911692## Обработка сигналов16931694Добавлено в версии 3.2.16951696Параметр командной строки [`-c/--catch`](https://python-all.ru/3.12/library/unittest.html#cmdoption-unittest-c) для unittest вместе с параметром `catchbreak` для [`unittest.main()`](https://python-all.ru/3.12/library/unittest.html#unittest.main) обеспечивают более удобную обработку control-C во время выполнения тестов. Когда поведение catch-break включено, control-C позволяет завершить текущий тест, после чего выполнение тестов завершается и выводятся все результаты на данный момент. Повторное нажатие control-C вызовет исключение [`KeyboardInterrupt`](https://python-all.ru/3.12/library/exceptions.html#KeyboardInterrupt) обычным образом.16971698Обработчик сигнала control-c старается оставаться совместимым с кодом или тестами, которые устанавливают собственный обработчик [`signal.SIGINT`](https://python-all.ru/3.12/library/signal.html#signal.SIGINT). Если обработчик `unittest` вызывается, но *не является* установленным обработчиком [`signal.SIGINT`](https://python-all.ru/3.12/library/signal.html#signal.SIGINT), то есть был заменён тестируемой системой и делегирован, то он вызывает стандартный обработчик. Обычно это ожидаемое поведение для кода, который заменяет установленный обработчик и делегирует ему. Для отдельных тестов, где требуется `unittest` отключить обработку control-c, можно использовать декоратор [`removeHandler()`](https://python-all.ru/3.12/library/unittest.html#unittest.removeHandler).16991700Существует несколько вспомогательных функций для разработчиков фреймворков, позволяющих включить обработку control-c в тестовых фреймворках.17011702#### `unittest.installHandler()`17031704Устанавливает обработчик control-c. Когда получен сигнал [`signal.SIGINT`](https://python-all.ru/3.12/library/signal.html#signal.SIGINT) (обычно в ответ на нажатие пользователем control-c), у всех зарегистрированных результатов вызывается [`stop()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.stop).17051706#### `unittest.registerResult(result)`17071708Регистрирует объект [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult) для обработки control-c. При регистрации результата сохраняется слабая ссылка на него, поэтому это не препятствует сборке мусора объекта результата.17091710Регистрация объекта [`TestResult`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult) не имеет побочных эффектов, если обработка control-c не включена, поэтому тестовые фреймворки могут безусловно регистрировать все создаваемые ими результаты, независимо от того, включена обработка или нет.17111712#### `unittest.removeResult(result)`17131714Удаляет зарегистрированный результат. После удаления результата [`stop()`](https://python-all.ru/3.12/library/unittest.html#unittest.TestResult.stop) больше не будет вызываться для этого объекта результата в ответ на control-c.17151716#### `unittest.removeHandler(function=None)`17171718При вызове без аргументов эта функция удаляет обработчик control-c, если он был установлен. Эту функцию также можно использовать как тестовый декоратор для временного удаления обработчика на время выполнения теста:17191720```python1721@unittest.removeHandler1722def test_signal_handling(self):1723 ...1724```1725