unittest.md
1> **Источник:** https://python-all.ru/3.2/library/unittest.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 25.3. [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) – Среда модульного тестирования89(Если вы уже знакомы с основными понятиями тестирования, можете перейти к [*списку методов assert*](https://python-all.ru/3.2/library/unittest.html#assert-methods).)1011Среда модульного тестирования Python, иногда называемая «PyUnit», является реализацией JUnit на языке Python, созданной Кентом Беком и Эрихом Гаммой. JUnit, в свою очередь, представляет собой Java-версию среды тестирования Smalltalk Кента Бека. Каждая из них является фактическим стандартом модульного тестирования для своего языка.1213[`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) поддерживает автоматизацию тестирования, совместное использование кода настройки и завершения для тестов, объединение тестов в коллекции и независимость тестов от фреймворка отчётов. Модуль [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) предоставляет классы, которые упрощают поддержку этих свойств для набора тестов.1415Для этого [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) поддерживает несколько важных концепций:1617**тестовая фикстура**1819*Тестовая фикстура*2021представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, и любые сопутствующие действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск серверного процесса.2223**тестовый случай**2425*Тестовый пример*2627– это наименьшая единица тестирования. Он проверяет определённый отклик на конкретный набор входных данных.2829[`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest)3031предоставляет базовый класс3233[`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase)3435, который может использоваться для создания новых тестовых примеров.3637**набор тестов**3839*Набор тестов*4041– это совокупность тестовых случаев, наборов тестов или и того, и другого. Он используется для объединения тестов, которые должны выполняться вместе.4243**исполнитель тестов**4445*Исполнитель тестов*4647– это компонент, который управляет выполнением тестов и предоставляет результат пользователю. Исполнитель может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение, указывающее на результаты выполнения тестов.4849Концепции тестового примера и тестового окружения поддерживаются через классы [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) и [`FunctionTestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.FunctionTestCase); первый следует использовать при создании новых тестов, а второй – при интеграции существующего тестового кода в фреймворк на основе [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest). При построении тестовых окружений с помощью [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) можно переопределять методы [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp) и [`tearDown()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.tearDown) для инициализации и очистки окружения. При использовании [`FunctionTestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.FunctionTestCase) для этих целей в конструктор можно передать существующие функции. При запуске теста сначала выполняется инициализация окружения; если она проходит успешно, метод очистки запускается после выполнения теста, независимо от его результата. Каждый экземпляр [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) используется для выполнения только одного тестового метода, поэтому для каждого теста создаётся новое окружение.5051Тестовые наборы реализуются классом [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite). Этот класс позволяет объединять отдельные тесты и тестовые наборы; при выполнении набора запускаются все тесты, добавленные непосредственно в набор и в «дочерние» тестовые наборы.5253Тестовый раннер – это объект, предоставляющий единственный метод `run()`, который принимает объект [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) в качестве параметра и возвращает объект результата. Класс [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult) предоставляется для использования в качестве объекта результата. [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) предоставляет [`TextTestRunner`](https://python-all.ru/3.2/library/unittest.html#unittest.TextTestRunner) в качестве примера тестового раннера, который по умолчанию выводит результаты тестов в стандартный поток ошибок. Альтернативные раннеры могут быть реализованы для других сред (например, графических) без необходимости наследования от какого-либо конкретного класса.5455> **См. также**56>57> **Модуль [`doctest`](https://python-all.ru/3.2/library/doctest.html#module-doctest)**58>59> Ещё один модуль поддержки тестирования с совершенно другим подходом.60>61> **[unittest2: обратный порт новых возможностей unittest для Python 2.4–2.6](https://python-all.ru/3.2/library/unittest.html)**62>63> В Python 2.7 в unittest было добавлено много новых возможностей, включая обнаружение тестов. unittest2 позволяет использовать эти возможности в более ранних версиях Python.64>65> **[Простое тестирование в Smalltalk: с шаблонами](https://python-all.ru/3.2/library/unittest.html)**66>67> Оригинальная статья Кента Бека о фреймворках тестирования, использующих шаблон, общий для68>69> [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest)70>71> .72>73> **[Nose](https://python-all.ru/3.2/library/unittest.html) и [py.test](https://python-all.ru/3.2/library/unittest.html)**74>75> Сторонние фреймворки unittest с более лёгким синтаксисом для написания тестов. Например,76>77> `assert func(10) == 42`78>79> .80>81> **[Таксономия инструментов тестирования Python](https://python-all.ru/3.2/library/unittest.html)**82>83> Обширный список инструментов тестирования Python, включая фреймворки функционального тестирования и библиотеки имитационных объектов (mock).84>85> **[Список рассылки по тестированию в Python](https://python-all.ru/3.2/library/unittest.html)**86>87> Группа по интересам для обсуждения тестирования и инструментов тестирования в Python.88>89> Скрипт `Tools/unittestgui/unittestgui.py` в дистрибутиве исходного кода Python – это инструмент с графическим интерфейсом для обнаружения и выполнения тестов. Он предназначен в первую очередь для упрощения работы тех, кто только знакомится с модульным тестированием. Для производственных сред рекомендуется запускать тесты с помощью системы непрерывной интеграции, такой как [Buildbot](https://python-all.ru/3.2/library/unittest.html), [Jenkins](https://python-all.ru/3.2/library/unittest.html) или [Hudson](https://python-all.ru/3.2/library/unittest.html).9091## 25.3.1. Простой пример9293Модуль [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) предоставляет богатый набор инструментов для создания и запуска тестов. В этом разделе показано, что даже небольшого подмножества этих инструментов достаточно для удовлетворения потребностей большинства пользователей.9495Вот короткий скрипт для тестирования трёх функций из модуля [`random`](https://python-all.ru/3.2/library/random.html#module-random):9697```python98import random99import unittest100101class TestSequenceFunctions(unittest.TestCase):102103 def setUp(self):104 self.seq = list(range(10))105106 def test_shuffle(self):107 # проверить, что перемешанная последовательность не теряет ни одного элемента108 random.shuffle(self.seq)109 self.seq.sort()110 self.assertEqual(self.seq, list(range(10)))111112 # должно вызывать исключение для неизменяемой последовательности113 self.assertRaises(TypeError, random.shuffle, (1,2,3))114115 def test_choice(self):116 element = random.choice(self.seq)117 self.assertTrue(element in self.seq)118119 def test_sample(self):120 with self.assertRaises(ValueError):121 random.sample(self.seq, 20)122 for element in random.sample(self.seq, 5):123 self.assertTrue(element in self.seq)124125if __name__ == '__main__':126 unittest.main()127```128129Тестовый пример создаётся путём создания подкласса [`unittest.TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase). Три отдельных теста определяются методами, имена которых начинаются с букв `test`. Это соглашение об именах сообщает программе запуска тестов, какие методы представляют собой тесты.130131Суть каждого теста сводится к вызову [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual) для проверки ожидаемого результата; [`assertTrue()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertTrue) – для проверки условия; или [`assertRaises()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaises) – чтобы убедиться, что возникает ожидаемое исключение. Эти методы используются вместо оператора [`assert`](https://python-all.ru/3.2/reference/simple_stmts.html#assert), чтобы средство запуска тестов могло накапливать все результаты и формировать отчёт.132133Если определён метод [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp), средство запуска тестов выполнит его перед каждым тестом. Аналогично, если определён метод [`tearDown()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.tearDown), средство запуска тестов вызовет его после каждого теста. В примере [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp) использовался для создания новой последовательности для каждого теста.134135Последний блок демонстрирует простой способ запуска тестов. [`unittest.main()`](https://python-all.ru/3.2/library/unittest.html#unittest.main) предоставляет интерфейс командной строки для тестового скрипта. При запуске из командной строки указанный скрипт выдаёт вывод, который выглядит так:136137```python138...139----------------------------------------------------------------------140Ran 3 tests in 0.000s141142OK143```144145Вместо [`unittest.main()`](https://python-all.ru/3.2/library/unittest.html#unittest.main) существуют другие способы запуска тестов с более точным контролем, менее лаконичным выводом и без необходимости запуска из командной строки. Например, последние две строки можно заменить на:146147```python148suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)149unittest.TextTestRunner(verbosity=2).run(suite)150```151152Запуск изменённого скрипта из интерпретатора или другого скрипта приводит к следующему выводу:153154```python155test_choice (__main__.TestSequenceFunctions) ... ok156test_sample (__main__.TestSequenceFunctions) ... ok157test_shuffle (__main__.TestSequenceFunctions) ... ok158159----------------------------------------------------------------------160Ran 3 tests in 0.110s161162OK163```164165Приведённые выше примеры показывают наиболее часто используемые возможности [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest), которых достаточно для удовлетворения многих повседневных потребностей тестирования. В остальной части документации подробно рассматривается полный набор возможностей, начиная с основ.166167## 25.3.2. Интерфейс командной строки168169Модуль unittest можно использовать из командной строки для запуска тестов из модулей, классов или даже отдельных тестовых методов:170171```python172python -m unittest test_module1 test_module2173python -m unittest test_module.TestClass174python -m unittest test_module.TestClass.test_method175```176177Можно передать список с любой комбинацией имён модулей, а также полных имён классов или методов.178179Тестовые модули также можно указывать по пути к файлу:180181```python182python -m unittest tests/test_something.py183```184185Это позволяет использовать автодополнение имён файлов в оболочке для указания тестового модуля. Указанный файл по-прежнему должен быть импортируем как модуль. Путь преобразуется в имя модуля путём удаления ‘.py’ и замены разделителей пути на ‘.’. Если требуется выполнить тестовый файл, который не импортируется как модуль, следует запускать файл напрямую.186187Можно запускать тесты с большей детализацией (повышенной подробностью), передав флаг -v:188189```python190python -m unittest -v test_module191```192193При запуске без аргументов запускается [*автоматическое обнаружение тестов*](https://python-all.ru/3.2/library/unittest.html#unittest-test-discovery):194195```python196python -m unittest197```198199Чтобы получить список всех параметров командной строки:200201```python202python -m unittest -h203```204205Изменено в версии 3.2: В более ранних версиях можно было запускать только отдельные тестовые методы, а не модули или классы.206207### 25.3.2.1. Параметры командной строки208209**unittest** поддерживает следующие параметры командной строки:210211#### `-b, --buffer`212213Потоки стандартного вывода и стандартной ошибки буферизируются во время выполнения теста. Вывод при успешном тесте отбрасывается. При ошибке или провале теста вывод выводится обычным образом и добавляется к сообщениям о неудаче.214215#### `-c, --catch`216217Нажатие Control-C во время выполнения теста дожидается завершения текущего теста, после чего выводит все накопленные результаты. Второе нажатие Control-C вызывает обычное исключение [`KeyboardInterrupt`](https://python-all.ru/3.2/library/exceptions.html#KeyboardInterrupt).218219См. раздел [Обработка сигналов](https://python-all.ru/3.2/library/unittest.html#signal-handling) с описанием функций, предоставляющих эту возможность.220221#### `-f, --failfast`222223Остановить выполнение теста при первой же ошибке или неудаче.224225Новое в версии 3.2: Были добавлены параметры командной строки `-b`, `-c` и `-f`.226227Командная строка также может использоваться для автоматического обнаружения тестов, для запуска всех тестов в проекте или только их части.228229## 25.3.3. Обнаружение тестов230231Новое в версии 3.2.232233Unittest поддерживает простое обнаружение тестов. Чтобы быть совместимыми с обнаружением тестов, все тестовые файлы должны быть [*модулями*](https://python-all.ru/3.2/tutorial/modules.html#tut-modules) или [*пакетами*](https://python-all.ru/3.2/tutorial/modules.html#tut-packages), импортируемыми из корневого каталога проекта (это означает, что их имена файлов должны быть валидными [*идентификаторами*](https://python-all.ru/3.2/reference/lexical_analysis.html#identifiers)).234235Обнаружение тестов реализовано в [`TestLoader.discover()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader.discover), но также может использоваться из командной строки. Основное использование в командной строке:236237```python238cd project_directory239python -m unittest discover240```241242> **Примечание**243>244> В качестве сокращения `python -m unittest` эквивалентно `python -m unittest discover`. Если требуется передать аргументы для обнаружения тестов, подкоманду `discover` необходимо указывать явно.245246Подкоманда `discover` имеет следующие параметры:247248#### `-v, --verbose`249250Подробный вывод251252#### `-s, --start-directory directory`253254Каталог для начала обнаружения (по умолчанию `.`)255256#### `-p, --pattern pattern`257258Шаблон для сопоставления тестовых файлов (по умолчанию `test*.py`)259260#### `-t, --top-level-directory directory`261262Корневой каталог проекта (по умолчанию – каталог начала поиска)263264Параметры [*-s*](https://python-all.ru/3.2/library/unittest.html#cmdoption-unittest-discover-s), [*-p*](https://python-all.ru/3.2/library/unittest.html#cmdoption-unittest-discover-p) и [*-t*](https://python-all.ru/3.2/library/unittest.html#cmdoption-unittest-discover-t) можно передавать в качестве позиционных аргументов в указанном порядке. Следующие две командные строки эквивалентны:265266```python267python -m unittest discover -s project_directory -p '*_test.py'268python -m unittest discover project_directory '*_test.py'269```270271Помимо пути можно передать имя пакета, например `myproject.subpackage.test`, в качестве начального каталога. Указанное имя пакета будет импортировано, а его расположение в файловой системе будет использовано как начальный каталог.272273> **Внимание**274>275> Обнаружение тестов загружает тесты путём их импорта. Когда обнаружение найдёт все тестовые файлы в указанном начальном каталоге, оно преобразует пути в имена пакетов для импорта. Например, `foo/bar/baz.py` будет импортирован как `foo.bar.baz`.276>277> Если пакет установлен глобально, и предпринимается попытка обнаружения тестов в другой копии пакета, то импорт *может* произойти из неправильного места. Если это произойдет, обнаружение тестов выдаст предупреждение и завершится.278>279> Если указать начальный каталог как имя пакета, а не путь к каталогу, то discover считает, что местоположение, из которого он импортирует, и есть то, которое вы имели в виду, поэтому предупреждение не появится.280281Тестовые модули и пакеты могут настраивать загрузку и обнаружение тестов с помощью [протокола load\_tests](https://python-all.ru/3.2/library/unittest.html#load-tests-protocol).282283## 25.3.4. Организация тестового кода284285Основными строительными блоками модульного тестирования являются *тестовые сценарии* – отдельные сценарии, которые необходимо настроить и проверить на корректность. В [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) тестовые сценарии представлены экземплярами [`unittest.TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase). Чтобы создать собственные тестовые сценарии, нужно написать подклассы [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) или использовать [`FunctionTestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.FunctionTestCase).286287Экземпляр класса, производного от [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), представляет собой объект, который может полностью выполнить один тестовый метод вместе с необязательным кодом настройки и очистки.288289Тестовый код экземпляра [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) должен быть полностью самодостаточным, чтобы его можно было запускать как изолированно, так и в произвольной комбинации с любым количеством других тестовых сценариев.290291Простейший подкласс [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) просто переопределяет метод `runTest()`, чтобы выполнить конкретный тестовый код:292293```python294import unittest295296class DefaultWidgetSizeTestCase(unittest.TestCase):297 def runTest(self):298 widget = Widget('The widget')299 self.assertEqual(widget.size(), (50, 50), 'incorrect default size')300```301302Обратите внимание, что для тестирования чего-либо используются один из методов `assert*()`, предоставляемых базовым классом [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase). Если тест не пройден, вызывается исключение, и [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) идентифицирует тестовый случай как *неудачу*. Любые другие исключения рассматриваются как *ошибки*. Это помогает определить, где находится проблема: *неудачи* вызваны неверными результатами – например, получено 5, а ожидалось 6. *Ошибки* вызваны некорректным кодом – например, [`TypeError`](https://python-all.ru/3.2/library/exceptions.html#TypeError), вызванный неправильным вызовом функции.303304Способ запуска тестового примера будет описан позже. Пока обратите внимание, что для создания экземпляра такого тестового примера мы вызываем его конструктор без аргументов:305306```python307testCase = DefaultWidgetSizeTestCase()308```309310Теперь таких тестовых примеров может быть много, и их настройка может повторяться. В приведённом выше случае создание `Widget` в каждом из 100 подклассов тестовых примеров Widget привело бы к некрасивому дублированию.311312К счастью, такой код настройки можно вынести, реализовав метод [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp), который тестовый фреймворк автоматически вызовет при запуске теста:313314```python315import unittest316317class SimpleWidgetTestCase(unittest.TestCase):318 def setUp(self):319 self.widget = Widget('The widget')320321class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):322 def runTest(self):323 self.assertEqual(self.widget.size(), (50,50),324 'incorrect default size')325326class WidgetResizeTestCase(SimpleWidgetTestCase):327 def runTest(self):328 self.widget.resize(100,150)329 self.assertEqual(self.widget.size(), (100,150),330 'wrong size after resize')331```332333Если метод [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp) возбуждает исключение во время выполнения теста, фреймворк считает, что в тесте произошла ошибка, и метод `runTest()` не будет выполнен.334335Аналогично можно предоставить метод [`tearDown()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.tearDown), который выполняет очистку после выполнения метода `runTest()`:336337```python338import unittest339340class SimpleWidgetTestCase(unittest.TestCase):341 def setUp(self):342 self.widget = Widget('The widget')343344 def tearDown(self):345 self.widget.dispose()346 self.widget = None347```348349Если [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp) выполнился успешно, метод [`tearDown()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.tearDown) будет запущен независимо от того, успешно ли выполнился `runTest()`.350351Такое рабочее окружение для тестового кода называется *фикстурой*.352353Часто множество маленьких тестовых случаев используют одну и ту же фикстуру. В этом случае пришлось бы создавать подклассы `SimpleWidgetTestCase` во множество маленьких классов с одним методом, таких как `DefaultWidgetSizeTestCase`. Это отнимает много времени и расстраивает, поэтому, по аналогии с JUnit, [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) предоставляет более простой механизм:354355```python356import unittest357358class WidgetTestCase(unittest.TestCase):359 def setUp(self):360 self.widget = Widget('The widget')361362 def tearDown(self):363 self.widget.dispose()364 self.widget = None365366 def test_default_size(self):367 self.assertEqual(self.widget.size(), (50,50),368 'incorrect default size')369370 def test_resize(self):371 self.widget.resize(100,150)372 self.assertEqual(self.widget.size(), (100,150),373 'wrong size after resize')374```375376Здесь мы не предоставили метод `runTest()`, а вместо этого предоставили два различных тестовых метода. Теперь каждый экземпляр класса будет запускать один из методов `test_*()`, причём `self.widget` создаётся и уничтожается отдельно для каждого экземпляра. При создании экземпляра необходимо указать, какой тестовый метод он будет выполнять. Это делается путём передачи имени метода в конструктор:377378```python379defaultSizeTestCase = WidgetTestCase('test_default_size')380resizeTestCase = WidgetTestCase('test_resize')381```382383Экземпляры тестовых случаев группируются в соответствии с тестируемыми возможностями. [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) предоставляет для этого механизм: *набор тестов*, представленный классом [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest).[`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite):384385```python386widgetTestSuite = unittest.TestSuite()387widgetTestSuite.addTest(WidgetTestCase('test_default_size'))388widgetTestSuite.addTest(WidgetTestCase('test_resize'))389```390391Для удобства запуска тестов, как мы увидим далее, рекомендуется предоставлять в каждом тестовом модуле вызываемый объект, возвращающий предварительно собранный набор тестов:392393```python394def suite():395 suite = unittest.TestSuite()396 suite.addTest(WidgetTestCase('test_default_size'))397 suite.addTest(WidgetTestCase('test_resize'))398 return suite399```400401или даже:402403```python404def suite():405 tests = ['test_default_size', 'test_resize']406407 return unittest.TestSuite(map(WidgetTestCase, tests))408```409410Поскольку создание подкласса [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) со множеством однотипно названных тестовых функций является распространённым шаблоном, [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) предоставляет класс [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader), который можно использовать для автоматизации процесса создания набора тестов и заполнения его отдельными тестами. Например,411412```python413suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)414```415416создаст набор тестов, который выполнит `WidgetTestCase.test_default_size()` и `WidgetTestCase.test_resize`. [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader) использует префикс имени метода `'test'` для автоматического определения тестовых методов.417418Обратите внимание, что порядок выполнения различных тестовых случаев определяется сортировкой имён тестовых функций в соответствии со встроенным порядком строк.419420Часто желательно группировать наборы тестов вместе, чтобы запускать тесты для всей системы за один раз. Это легко, поскольку экземпляры [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) можно добавлять в [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) так же, как экземпляры [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) можно добавлять в [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite):421422```python423suite1 = module1.TheTestSuite()424suite2 = module2.TheTestSuite()425alltests = unittest.TestSuite([suite1, suite2])426```427428Определения тестовых сценариев и тестовых наборов можно размещать в тех же модулях, что и тестируемый код (например, `widget.py`), но есть несколько преимуществ в размещении тестового кода в отдельном модуле, например `test_widget.py`:429430- Тестовый модуль можно запускать автономно из командной строки.431- Тестовый код проще отделить от поставляемого кода.432- Меньше соблазна изменять тестовый код, чтобы подогнать его под тестируемый код, без веской причины.433- Тестовый код должен изменяться гораздо реже, чем тестируемый код.434- Тестируемый код проще поддаётся рефакторингу.435- Тесты для модулей, написанных на C, всё равно должны быть в отдельных модулях – так почему бы не придерживаться этого подхода?436- Если стратегия тестирования меняется, нет необходимости изменять исходный код.437438## 25.3.5. Повторное использование старого тестового кода439440Некоторые пользователи могут обнаружить, что у них есть существующий тестовый код, который они хотели бы запускать из [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest), без преобразования каждой старой тестовой функции в подкласс [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase).441442По этой причине [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) предоставляет класс [`FunctionTestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.FunctionTestCase). Этот подкласс [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) можно использовать для обёртывания существующей тестовой функции. Также можно предоставить функции настройки и очистки.443444Рассмотрим следующую тестовую функцию:445446```python447def testSomething():448 something = makeSomething()449 assert something.name is not None450 # ...451```452453можно создать эквивалентный экземпляр тестового случая следующим образом:454455```python456testcase = unittest.FunctionTestCase(testSomething)457```458459Если есть дополнительные методы настройки и очистки, которые должны вызываться в рамках работы тестового случая, их также можно предоставить следующим образом:460461```python462testcase = unittest.FunctionTestCase(testSomething,463 setUp=makeSomethingDB,464 tearDown=deleteSomethingDB)465```466467Чтобы упростить миграцию существующих наборов тестов, [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) поддерживает возбуждение тестами [`AssertionError`](https://python-all.ru/3.2/library/exceptions.html#AssertionError) для обозначения провала теста. Однако рекомендуется использовать явные методы `TestCase.fail*()` и `TestCase.assert*()`, так как будущие версии [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) могут обрабатывать [`AssertionError`](https://python-all.ru/3.2/library/exceptions.html#AssertionError) иначе.468469> **Примечание**470>471> Хотя [`FunctionTestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.FunctionTestCase) можно использовать для быстрого преобразования существующей тестовой базы в систему на основе [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest), этот подход не рекомендуется. Уделив время созданию правильных подклассов [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), можно значительно упростить будущий рефакторинг тестов.472473В некоторых случаях существующие тесты могут быть написаны с использованием модуля [`doctest`](https://python-all.ru/3.2/library/doctest.html#module-doctest). Если это так, [`doctest`](https://python-all.ru/3.2/library/doctest.html#module-doctest) предоставляет класс `DocTestSuite`, который может автоматически создавать экземпляры [`unittest.TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) из существующих тестов на основе [`doctest`](https://python-all.ru/3.2/library/doctest.html#module-doctest).474475## 25.3.6. Пропуск тестов и ожидаемые сбои476477Новое в версии 3.1.478479Unittest поддерживает пропуск отдельных тестовых методов и даже целых классов тестов. Кроме того, он поддерживает пометку теста как «ожидаемого сбоя» – теста, который сломан и будет провален, но не должен учитываться как сбой в [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult).480481Пропуск теста – это просто использование [`skip()`](https://python-all.ru/3.2/library/unittest.html#unittest.skip) [*декоратора*](https://python-all.ru/3.2/glossary.html#term-decorator) или одного из его условных вариантов.482483Базовый пропуск выглядит так:484485```python486class MyTestCase(unittest.TestCase):487488 @unittest.skip("demonstrating skipping")489 def test_nothing(self):490 self.fail("shouldn't happen")491492 @unittest.skipIf(mylib.__version__ < (1, 3),493 "not supported in this library version")494 def test_format(self):495 # Тесты, которые работают только для определённой версии библиотеки.496 pass497498 @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")499 def test_windows_support(self):500 # код тестирования для Windows501 pass502```503504Это вывод приведённого выше примера в подробном режиме:505506```python507test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'508test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'509test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'510511----------------------------------------------------------------------512Ran 3 tests in 0.005s513514OK (skipped=3)515```516517Классы можно пропускать так же, как методы:518519```python520@unittest.skip("showing class skipping")521class MySkippedTestCase(unittest.TestCase):522 def test_not_run(self):523 pass524```525526[`TestCase.setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp) также может пропустить тест. Это полезно, когда ресурс, который необходимо настроить, недоступен.527528Ожидаемые сбои используют декоратор [`expectedFailure()`](https://python-all.ru/3.2/library/unittest.html#unittest.expectedFailure).529530```python531class ExpectedFailureTestCase(unittest.TestCase):532 @unittest.expectedFailure533 def test_fail(self):534 self.assertEqual(1, 0, "broken")535```536537Легко создать собственные декораторы пропуска, написав декоратор, который вызывает [`skip()`](https://python-all.ru/3.2/library/unittest.html#unittest.skip) для теста, когда его нужно пропустить. Этот декоратор пропускает тест, если переданный объект не имеет определённого атрибута:538539```python540def skipUnlessHasattr(obj, attr):541 if hasattr(obj, attr):542 return lambda func: func543 return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))544```545546Следующие декораторы реализуют пропуск тестов и ожидаемые сбои:547548#### `@unittest.skip(reason)`549550Безусловно пропускает декорированный тест. Параметр *reason* должен описывать причину пропуска теста.551552#### `@unittest.skipIf(condition, reason)`553554Пропустить декорированный тест, если *condition* истинно.555556#### `@unittest.skipUnless(condition, reason)`557558Пропустить декорированный тест, если *condition* не истинно.559560#### `@unittest.expectedFailure`561562Помечает тест как ожидаемый сбой. Если тест завершается ошибкой при запуске, он не учитывается как сбой.563564#### `exception unittest.SkipTest(reason)`565566Это исключение возбуждается для пропуска теста.567568Обычно можно использовать [`TestCase.skipTest()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.skipTest) или один из декораторов пропуска, вместо прямого возбуждения этого исключения.569570Пропущенные тесты не будут выполнять `setUp()` или `tearDown()`. Пропущенные классы не будут выполнять `setUpClass()` или `tearDownClass()`.571572## 25.3.7. Классы и функции573574Этот раздел подробно описывает API [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest).575576### 25.3.7.1. Тестовые случаи577578#### `class unittest.TestCase(methodName='runTest')`579580Экземпляры класса [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) представляют наименьшие тестируемые единицы во вселенной [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest). Этот класс предназначен для использования в качестве базового класса, при этом конкретные тесты реализуются конкретными подклассами. Данный класс реализует интерфейс, необходимый тестовому раннеру для управления тестом, а также методы, которые тестовый код может использовать для проверки и сообщения о различных типах сбоев.581582Каждый экземпляр [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) запускает один тестовый метод: метод с именем *methodName*. Как упоминалось ранее, был пример, выглядевший следующим образом:583584```python585def suite():586 suite = unittest.TestSuite()587 suite.addTest(WidgetTestCase('test_default_size'))588 suite.addTest(WidgetTestCase('test_resize'))589 return suite590```591592Здесь создаются два экземпляра `WidgetTestCase`, каждый из которых выполняет один тест.593594Изменено в версии 3.2: [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) можно успешно создать без указания имени метода. Это упрощает эксперименты с [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) из интерактивного интерпретатора.595596*methodName* по умолчанию равен `runTest()`.597598Экземпляры [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) предоставляют три группы методов: одна группа используется для запуска теста, другая – реализацией теста для проверки условий и сообщения об ошибках, а также некоторые запрашивающие методы, позволяющие получать информацию о самом тесте.599600Методы первой группы (выполнение теста):601602#### `setUp()`603604Метод, вызываемый для подготовки тестового окружения (fixture). Он вызывается непосредственно перед вызовом тестового метода; любое исключение, возбуждённое этим методом, будет считаться ошибкой, а не неудачей теста. Реализация по умолчанию ничего не делает.605606#### `tearDown()`607608Метод, вызываемый сразу после вызова тестового метода и записи результата. Он вызывается, даже если тестовый метод возбудил исключение, поэтому реализация в подклассах должна быть особенно внимательна при проверке внутреннего состояния. Любое исключение, возбуждённое этим методом, будет считаться ошибкой, а не неудачей теста. Этот метод вызывается только в случае успешного выполнения [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp), независимо от результата тестового метода. Реализация по умолчанию ничего не делает.609610#### `setUpClass()`611612Метод класса, вызываемый перед запуском тестов в отдельном классе. `setUpClass` вызывается с классом в качестве единственного аргумента и должен быть декорирован как [`classmethod()`](https://python-all.ru/3.2/library/functions.html#classmethod):613614```python615@classmethod616def setUpClass(cls):617 ...618```619620См. [Фикстуры классов и модулей](https://python-all.ru/3.2/library/unittest.html#class-and-module-fixtures) для получения дополнительных сведений.621622Новое в версии 3.2.623624#### `tearDownClass()`625626Метод класса, вызываемый после завершения тестов в отдельном классе. `tearDownClass` вызывается с классом в качестве единственного аргумента и должен быть декорирован как [`classmethod()`](https://python-all.ru/3.2/library/functions.html#classmethod):627628```python629@classmethod630def tearDownClass(cls):631 ...632```633634См. [Фикстуры классов и модулей](https://python-all.ru/3.2/library/unittest.html#class-and-module-fixtures) для получения дополнительных сведений.635636Новое в версии 3.2.637638#### `run(result=None)`639640Запускает тест, собирая результат в объект результата теста, переданный как *result*. Если *result* опущен или равен `None`, создаётся временный объект результата (вызовом метода [`defaultTestResult()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.defaultTestResult)) и используется. Объект результата не возвращается вызывающему коду [`run()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.run).641642Тот же эффект можно получить, просто вызвав экземпляр [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase).643644#### `skipTest(reason)`645646Вызов этого метода во время выполнения тестового метода или [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp) пропускает текущий тест. См. [*Пропуск тестов и ожидаемые сбои*](https://python-all.ru/3.2/library/unittest.html#unittest-skipping) для получения дополнительной информации.647648Новое в версии 3.1.649650#### `debug()`651652Запускает тест без сбора результата. Это позволяет исключениям, возникшим в тесте, распространяться до вызывающего кода, и может использоваться для поддержки запуска тестов под отладчиком.653654Класс [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) предоставляет ряд методов для проверки и сообщения об ошибках, таких как:655656| Метод | Проверяет, что | Новое в |657| --- | --- | --- |658| [`assertEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual) | `a == b` | |659| [`assertNotEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotEqual) | `a != b` | |660| [`assertTrue(x)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertTrue) | `bool(x) is True` | |661| [`assertFalse(x)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertFalse) | `bool(x) is False` | |662| [`assertIs(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertIs) | `a is b` | 3.1 |663| [`assertIsNot(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertIsNot) | `a is not b` | 3.1 |664| [`assertIsNone(x)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertIsNone) | `x is None` | 3.1 |665| [`assertIsNotNone(x)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertIsNotNone) | `x is not None` | 3.1 |666| [`assertIn(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertIn) | `a in b` | 3.1 |667| [`assertNotIn(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotIn) | `a not in b` | 3.1 |668| [`assertIsInstance(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertIsInstance) | `isinstance(a, b)` | 3.2 |669| [`assertNotIsInstance(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotIsInstance) | `not isinstance(a, b)` | 3.2 |670671Все assert-методы (кроме [`assertRaises()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaises), [`assertRaisesRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaisesRegex), [`assertWarns()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertWarns), [`assertWarnsRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertWarnsRegex)) принимают аргумент *msg*, который, если указан, используется как сообщение об ошибке при неудаче (см. также [`longMessage`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.longMessage)).672673#### `assertEqual(first, second, msg=None)`674675Проверяет, что *first* и *second* равны. Если значения не равны, тест завершится с ошибкой.676677Кроме того, если *first* и *second* имеют один и тот же тип и являются одним из list, tuple, dict, set, frozenset или str, или любым типом, который подкласс регистрирует с помощью [`addTypeEqualityFunc()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.addTypeEqualityFunc), то будет вызвана функция сравнения, специфичная для этого типа, чтобы сгенерировать более полезное сообщение об ошибке по умолчанию (см. также [*список методов для конкретных типов*](https://python-all.ru/3.2/library/unittest.html#type-specific-methods)).678679Изменено в версии 3.1: Добавлен автоматический вызов функции сравнения для конкретного типа.680681Изменено в версии 3.2: [`assertMultiLineEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertMultiLineEqual) добавлена как функция сравнения по умолчанию для строк.682683#### `assertNotEqual(first, second, msg=None)`684685Проверяет, что *first* и *second* не равны. Если значения равны, тест завершится с ошибкой.686687#### `assertTrue(expr, msg=None)`688689#### `assertFalse(expr, msg=None)`690691Проверяет, что *expr* истинно (или ложно).692693Обратите внимание, что это эквивалентно `bool(expr) is True`, а не `expr is True` (для последнего используйте `assertIs(expr, True)`). Этого метода также следует избегать, когда доступны более специфичные методы (например, `assertEqual(a, b)` вместо `assertTrue(a == b)`), поскольку они предоставляют лучшее сообщение об ошибке в случае неудачи.694695#### `assertIs(first, second, msg=None)`696697#### `assertIsNot(first, second, msg=None)`698699Проверяет, что *first* и *second* вычисляются (или не вычисляются) в один и тот же объект.700701Новое в версии 3.1.702703#### `assertIsNone(expr, msg=None)`704705#### `assertIsNotNone(expr, msg=None)`706707Проверяет, что *expr* равен (или не равен) None.708709Новое в версии 3.1.710711#### `assertIn(first, second, msg=None)`712713#### `assertNotIn(first, second, msg=None)`714715Проверяет, находится ли *first* в *second* (или не находится).716717Новое в версии 3.1.718719#### `assertIsInstance(obj, cls, msg=None)`720721#### `assertNotIsInstance(obj, cls, msg=None)`722723Проверяет, что *obj* является (или не является) экземпляром *cls* (который может быть классом или кортежем классов, как поддерживается функцией [`isinstance()`](https://python-all.ru/3.2/library/functions.html#isinstance)). Чтобы проверить точный тип, используйте [`assertIs(type(obj), cls)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertIs).724725Новое в версии 3.2.726727Также можно проверить, что исключения и предупреждения возбуждаются с помощью следующих методов:728729| Метод | Проверяет, что | Новое в |730| --- | --- | --- |731| [`assertRaises(exc, fun, *args, **kwds)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaises) | `fun(*args, **kwds)` возбуждает *exc* | |732| [`assertRaisesRegex(exc, re, fun, *args, **kwds)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaisesRegex) | `fun(*args, **kwds)` вызывает *exc* и сообщение соответствует *re* | 3.1 |733| [`assertWarns(warn, fun, *args, **kwds)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertWarns) | `fun(*args, **kwds)` возбуждает *warn* | 3.2 |734| [`assertWarnsRegex(warn, re, fun, *args, **kwds)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertWarnsRegex) | `fun(*args, **kwds)` вызывает *warn* и сообщение соответствует *re* | 3.2 |735736#### `assertRaises(exception, callable, *args, **kwds)`737738#### `assertRaises(exception)`739740Проверяет, что исключение возбуждается, когда *callable* вызывается с любыми позиционными или ключевыми аргументами, которые также передаются в [`assertRaises()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaises). Тест проходит, если возбуждается *исключение*, является ошибкой, если возбуждается другое исключение, или завершается неудачей, если исключение не возбуждено. Чтобы перехватить любую из группы исключений, можно передать кортеж, содержащий классы исключений, как *исключение*.741742Если указан только аргумент *исключение*, возвращается контекстный менеджер, так что тестируемый код можно писать встроенно, а не в виде функции:743744```python745with self.assertRaises(SomeException):746 do_something()747```748749Менеджер контекста сохранит перехваченный объект исключения в своем атрибуте `исключение`. Это может быть полезно, если требуется выполнить дополнительные проверки возбужденного исключения:750751```python752with self.assertRaises(SomeException) as cm:753 do_something()754755the_exception = cm.exception756self.assertEqual(the_exception.error_code, 3)757```758759Изменено в версии 3.1: Добавлена возможность использовать [`assertRaises()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaises) в качестве контекстного менеджера.760761Изменено в версии 3.2: Добавлен атрибут `исключение`.762763#### `assertRaisesRegex(exception, regex, callable, *args, **kwds)`764765#### `assertRaisesRegex(exception, regex)`766767Как и [`assertRaises()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaises), но также проверяет, что *regex* соответствует строковому представлению возбужденного исключения. *regex* может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящей для использования в [`re.search()`](https://python-all.ru/3.2/library/re.html#re.search). Примеры:768769```python770self.assertRaisesRegex(ValueError, 'invalid literal for.*XYZ$',771 int, 'XYZ')772```773774или:775776```python777with self.assertRaisesRegex(ValueError, 'literal'):778 int('XYZ')779```780781Новое в версии 3.1: под именем `assertRaisesRegexp`.782783Изменено в версии 3.2: Переименовано в [`assertRaisesRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaisesRegex).784785#### `assertWarns(warning, callable, *args, **kwds)`786787#### `assertWarns(warning)`788789Проверяет, что предупреждение вызывается, когда *callable* вызывается с любыми позиционными или именованными аргументами, которые также передаются в [`assertWarns()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertWarns). Тест проходит, если *warning* вызывается, и не проходит в противном случае. Также любое неожиданное исключение считается ошибкой. Чтобы перехватить любое из группы предупреждений, можно передать кортеж классов предупреждений в качестве *warnings*.790791Если указан только аргумент *warning*, возвращается контекстный менеджер, так что тестируемый код можно писать встроенно, а не в виде функции:792793```python794with self.assertWarns(SomeWarning):795 do_something()796```797798Контекстный менеджер сохраняет перехваченный объект предупреждения в своём атрибуте `warning`, а исходную строку, вызвавшую предупреждение, – в атрибутах `filename` и `lineno`. Это может быть полезно, если требуется выполнить дополнительные проверки вызванного исключения:799800```python801with self.assertWarns(SomeWarning) as cm:802 do_something()803804self.assertIn('myfile.py', cm.filename)805self.assertEqual(320, cm.lineno)806```807808Этот метод работает независимо от фильтров предупреждений, установленных на момент его вызова.809810Новое в версии 3.2.811812#### `assertWarnsRegex(warning, regex, callable, *args, **kwds)`813814#### `assertWarnsRegex(warning, regex)`815816Аналогично [`assertWarns()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertWarns), но также проверяет, что *regex* соответствует сообщению перехваченного предупреждения. *regex* может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, пригодное для использования с [`re.search()`](https://python-all.ru/3.2/library/re.html#re.search). Пример:817818```python819self.assertWarnsRegex(DeprecationWarning,820 r'legacy_function\(\) is deprecated',821 legacy_function, 'XYZ')822```823824или:825826```python827with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):828 frobnicate('/etc/passwd')829```830831Новое в версии 3.2.832833Существуют также другие методы для выполнения более специфических проверок, например:834835| Метод | Проверяет, что | Новое в |836| --- | --- | --- |837| [`assertAlmostEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertAlmostEqual) | `round(a-b, 7) == 0` | |838| [`assertNotAlmostEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) | `round(a-b, 7) != 0` | |839| [`assertGreater(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertGreater) | `a > b` | 3.1 |840| [`assertGreaterEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertGreaterEqual) | `a >= b` | 3.1 |841| [`assertLess(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertLess) | `a < b` | 3.1 |842| [`assertLessEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertLessEqual) | `a <= b` | 3.1 |843| [`assertRegex(s, re)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRegex) | `regex.search(s)` | 3.1 |844| [`assertNotRegex(s, re)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotRegex) | `not regex.search(s)` | 3.2 |845| [`assertCountEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertCountEqual) | *a* и *b* содержат одни и те же элементы в одинаковом количестве, независимо от их порядка | 3.2 |846847#### `assertAlmostEqual(first, second, places=7, msg=None, delta=None)`848849#### `assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)`850851Проверяет, что *first* и *second* приблизительно (или не приблизительно) равны, вычисляя разность, округляя до заданного числа десятичных *знаков* (по умолчанию 7) и сравнивая с нулём. Обратите внимание, что эти методы округляют значения до заданного числа *десятичных знаков* (т.е. как функция [`round()`](https://python-all.ru/3.2/library/functions.html#round)), а не до *значащих цифр*.852853Если указан *delta* вместо *places*, то разница между *first* и *second* должна быть меньше (или больше) *delta*.854855Указание одновременно *delta* и *places* вызывает исключение `TypeError`.856857Изменено в версии 3.2: [`assertAlmostEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertAlmostEqual) теперь автоматически считает почти равными объекты, которые сравниваются как равные. [`assertNotAlmostEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) автоматически завершается ошибкой, если объекты сравниваются как равные. Добавлен именованный аргумент *delta*.858859#### `assertGreater(first, second, msg=None)`860861#### `assertGreaterEqual(first, second, msg=None)`862863#### `assertLess(first, second, msg=None)`864865#### `assertLessEqual(first, second, msg=None)`866867Проверяет, что *first* соответственно \>, \>=, \< или \<= по отношению к *second* в зависимости от имени метода. Если это не так, тест завершается ошибкой:868869```python870>>> self.assertGreaterEqual(3, 4)871AssertionError: "3" unexpectedly not greater than or equal to "4"872```873874Новое в версии 3.1.875876#### `assertRegex(text, regex, msg=None)`877878#### `assertNotRegex(text, regex, msg=None)`879880Проверяет, что поиск *regex* соответствует (или не соответствует) *text*. В случае неудачи сообщение об ошибке будет содержать шаблон и *text* (или шаблон и часть *text*, которая неожиданно совпала). *regex* может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, пригодной для использования в [`re.search()`](https://python-all.ru/3.2/library/re.html#re.search).881882Новое в версии 3.1: под именем `assertRegexpMatches`.883884Изменено в версии 3.2: Метод `assertRegexpMatches()` был переименован в [`assertRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRegex).885886Новое в версии 3.2: [`assertNotRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotRegex).887888#### `assertDictContainsSubset(subset, dictionary, msg=None)`889890Проверяет, являются ли пары ключ/значение в *словаре* надмножеством пар в *subset*. Если нет, генерируется сообщение об ошибке со списком отсутствующих ключей и несовпадающих значений.891892Обратите внимание: аргументы передаются в порядке, обратном тому, что подразумевается названием метода. Вместо этого рассмотрите использование методов множеств на [*представлениях словаря*](https://python-all.ru/3.2/library/stdtypes.html#dict-views), например: `d.keys() <= e.keys()` или `d.items() <= d.items()`.893894Новое в версии 3.1.895896Устарело с версии 3.2.897898#### `assertCountEqual(first, second, msg=None)`899900Проверяет, что последовательность *first* содержит те же элементы, что и *second*, независимо от их порядка. Если нет, генерируется сообщение об ошибке с перечислением различий между последовательностями.901902Дублирующиеся элементы *не* игнорируются при сравнении *first* и *second*. Проверяется, что каждый элемент имеет одинаковое количество в обеих последовательностях. Эквивалентно: `assertEqual(Counter(list(first)), Counter(list(second)))` но также работает с последовательностями нехэшируемых объектов.903904Новое в версии 3.2.905906#### `assertSameElements(first, second, msg=None)`907908Проверяет, что последовательность *first* содержит те же элементы, что и *second*, независимо от их порядка. Если это не так, генерируется сообщение об ошибке с перечислением различий между последовательностями.909910Дублирующиеся элементы игнорируются при сравнении *first* и *second*. Это эквивалентно `assertEqual(set(first), set(second))`, но работает также с последовательностями нехешируемых объектов. Поскольку дубликаты игнорируются, этот метод устарел в пользу [`assertCountEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertCountEqual).911912Новое в версии 3.1.913914Устарело с версии 3.2.915916Метод [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual) направляет проверку равенства для объектов одного типа к различным методам, специфичным для типа. Эти методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощью [`addTypeEqualityFunc()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.addTypeEqualityFunc):917918#### `addTypeEqualityFunc(typeobj, function)`919920Регистрирует метод, специфичный для типа, который вызывается [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual) для проверки, равны ли два объекта одного и того же *typeobj* (не подклассы). *function* должен принимать два позиционных аргумента и третий именованный аргумент msg=None, как и [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual). Он должен вызывать исключение [`self.failureException(msg)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.failureException) при обнаружении неравенства между первыми двумя параметрами – возможно, предоставляя полезную информацию и подробно объясняя неравенства в сообщении об ошибке.921922Новое в версии 3.1.923924Список методов, специфичных для типа, автоматически используемых [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual), приведен в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать эти методы напрямую.925926| Метод | Используется для сравнения | Новое в |927| --- | --- | --- |928| [`assertMultiLineEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertMultiLineEqual) | строки | 3.1 |929| [`assertSequenceEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertSequenceEqual) | последовательности | 3.1 |930| [`assertListEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertListEqual) | списки | 3.1 |931| [`assertTupleEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertTupleEqual) | кортежи | 3.1 |932| [`assertSetEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertSetEqual) | множества или неизменяемые множества | 3.1 |933| [`assertDictEqual(a, b)`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertDictEqual) | словари | 3.1 |934935#### `assertMultiLineEqual(first, second, msg=None)`936937Проверяет, что многострочная строка *first* равна строке *second*. При неравенстве в сообщение об ошибке будет включена разница между двумя строками с выделением отличий. Этот метод используется по умолчанию при сравнении строк с [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual).938939Новое в версии 3.1.940941#### `assertSequenceEqual(first, second, msg=None, seq_type=None)`942943Проверяет, что две последовательности равны. Если передан *seq\_type*, то *first* и *second* должны быть экземплярами *seq\_type*, иначе будет вызвана ошибка. Если последовательности различаются, формируется сообщение об ошибке, показывающее разницу между ними.944945Этот метод не вызывается напрямую [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual), но используется для реализации [`assertListEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertListEqual) и [`assertTupleEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertTupleEqual).946947Новое в версии 3.1.948949#### `assertListEqual(first, second, msg=None)`950951#### `assertTupleEqual(first, second, msg=None)`952953Проверяет, что два списка или кортежа равны. Если нет, формируется сообщение об ошибке, показывающее только различия между ними. Ошибка также возникает, если какой-либо из параметров имеет неправильный тип. Эти методы используются по умолчанию при сравнении списков или кортежей с [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual).954955Новое в версии 3.1.956957#### `assertSetEqual(first, second, msg=None)`958959Проверяет, что два множества равны. Если нет, формируется сообщение об ошибке, в котором перечислены различия между множествами. Этот метод используется по умолчанию при сравнении множеств или frozensets с [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual).960961Завершается ошибкой, если *first* или *second* не имеют метода [`set.difference()`](https://python-all.ru/3.2/library/stdtypes.html#set.difference) .962963Новое в версии 3.1.964965#### `assertDictEqual(first, second, msg=None)`966967Проверяет, что два словаря равны. Если нет, формируется сообщение об ошибке, показывающее различия в словарях. Этот метод будет использоваться по умолчанию для сравнения словарей в вызовах [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual).968969Новое в версии 3.1.970971Наконец, [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) предоставляет следующие методы и атрибуты:972973#### `fail(msg=None)`974975Безусловно сообщает о провале теста, с *msg* или `None` в качестве сообщения об ошибке.976977#### `failureException`978979Этот атрибут класса задаёт исключение, возбуждаемое тестовым методом. Если тестовой платформе нужно использовать специализированное исключение, возможно, для передачи дополнительной информации, она должна создать подкласс этого исключения, чтобы корректно работать с платформой. Начальное значение этого атрибута – [`AssertionError`](https://python-all.ru/3.2/library/exceptions.html#AssertionError).980981#### `longMessage`982983Если установлено в `True`, то любое явное сообщение об ошибке, переданное в [*assert-методы*](https://python-all.ru/3.2/library/unittest.html#assert-methods), будет добавлено в конец стандартного сообщения об ошибке. Стандартные сообщения содержат полезную информацию о вовлечённых объектах, например, сообщение от assertEqual показывает repr двух неравных объектов. Установка этого атрибута в `True` позволяет иметь пользовательское сообщение об ошибке в дополнение к стандартному.984985Этот атрибут по умолчанию равен `True`. Если установлен в False, то пользовательское сообщение, переданное методу assert, подавит стандартное сообщение.986987Настройку класса можно переопределить в отдельных тестах, назначив атрибут экземпляра в `True` или `False` перед вызовом методов assert.988989Новое в версии 3.1.990991#### `maxDiff`992993Этот атрибут управляет максимальной длиной вывода различий методами assert, которые сообщают о различиях при неудаче. По умолчанию он равен 80\*8 символов. Методы assert, на которые влияет этот атрибут: [`assertSequenceEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertSequenceEqual) (включая все методы сравнения последовательностей, которые делегируют ему), [`assertDictEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertDictEqual) и [`assertMultiLineEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertMultiLineEqual).994995Установка `maxDiff` в None означает, что нет максимальной длины различий.996997Новое в версии 3.2.998999Тестовые фреймворки могут использовать следующие методы для сбора информации о тесте:10001001#### `countTestCases()`10021003Возвращает количество тестов, представленных этим тестовым объектом. Для экземпляров [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) это значение всегда равно `1`.10041005#### `defaultTestResult()`10061007Возвращает экземпляр класса результата теста, который следует использовать для этого класса тестового случая (если другой экземпляр результата не предоставлен методу [`run()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.run)).10081009Для экземпляров [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) это всегда будет экземпляр [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult); подклассы [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) должны переопределять это при необходимости.10101011#### `id()`10121013Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя тестового метода, включая имя модуля и класса.10141015#### `shortDescription()`10161017Возвращает описание теста или `None`, если описание не было предоставлено. Реализация по умолчанию этого метода возвращает первую строку докстринга тестового метода, если она есть, или `None`.10181019Изменено в версии 3.1: В версии 3.1 поведение было изменено: имя теста стало добавляться в краткое описание, даже если присутствовала docstring. Это вызвало проблемы совместимости с расширениями unittest, и в Python 3.2 добавление имени теста было перенесено в [`TextTestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TextTestResult).10201021#### `addCleanup(function, *args, **kwargs)`10221023Добавляет функцию, которая будет вызвана после [`tearDown()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.tearDown) для очистки ресурсов, используемых во время теста. Функции будут вызываться в порядке, обратном порядку их добавления (LIFO). Они вызываются с теми аргументами и именованными аргументами, которые были переданы в [`addCleanup()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.addCleanup) при их добавлении.10241025Если [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp) завершается неудачей, так что [`tearDown()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.tearDown) не вызывается, то все добавленные функции очистки всё равно будут вызваны.10261027Новое в версии 3.1.10281029#### `doCleanups()`10301031Этот метод вызывается безусловно после [`tearDown()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.tearDown), или после [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp), если [`setUp()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.setUp) возбуждает исключение.10321033Он отвечает за вызов всех функций очистки, добавленных с помощью [`addCleanup()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.addCleanup). Если нужно, чтобы функции очистки вызывались *до* [`tearDown()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.tearDown), то можно вызвать [`doCleanups()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.doCleanups) самостоятельно.10341035[`doCleanups()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.doCleanups) извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любое время.10361037Новое в версии 3.1.10381039#### `class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)`10401041Этот класс реализует часть интерфейса [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), которая позволяет тестовому раннеру управлять тестом, но не предоставляет методы, которые тестовый код может использовать для проверки и сообщения об ошибках. Он используется для создания тестовых случаев с использованием устаревшего тестового кода, позволяя интегрировать его в тестовый фреймворк на основе [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest).10421043#### 25.3.7.1.1. Устаревшие псевдонимы10441045По историческим причинам некоторые методы [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) имели один или несколько псевдонимов, которые теперь устарели. В следующей таблице перечислены правильные имена вместе с их устаревшими псевдонимами:10461047> | Имя метода | Устаревший псевдоним | Устаревший псевдоним |1048> | --- | --- | --- |1049> | [`assertEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertEqual) | failUnlessEqual | assertEquals |1050> | [`assertNotEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotEqual) | failIfEqual | assertNotEquals |1051> | [`assertTrue()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertTrue) | failUnless | assert\_ |1052> | [`assertFalse()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertFalse) | failIf | |1053> | [`assertRaises()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaises) | failUnlessRaises | |1054> | [`assertAlmostEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertAlmostEqual) | failUnlessAlmostEqual | assertAlmostEquals |1055> | [`assertNotAlmostEqual()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) | failIfAlmostEqual | assertNotAlmostEquals |1056> | [`assertRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRegex) | | assertRegexpMatches |1057> | [`assertRaisesRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaisesRegex) | | assertRaisesRegexp |1058>1059> Устарело с версии 3.1: псевдонимы fail\*, перечисленные во втором столбце.1060>1061> Устарело с версии 3.2: псевдонимы assert\*, перечисленные в третьем столбце.1062>1063> Устарело с версии 3.2: `assertRegexpMatches` и `assertRaisesRegexp` были переименованы в [`assertRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRegex) и [`assertRaisesRegex()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.assertRaisesRegex)10641065### 25.3.7.2. Группировка тестов10661067#### `class unittest.TestSuite(tests=())`10681069Этот класс представляет собой агрегацию отдельных тестовых случаев и тестовых наборов. Он предоставляет интерфейс, необходимый тестовому раннеру, чтобы его можно было запускать как любой другой тестовый случай. Запуск экземпляра [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) равносилен итерации по набору с запуском каждого теста по отдельности.10701071Если задан *tests*, он должен быть итерабельным объектом, содержащим отдельные тестовые примеры или другие тестовые наборы, которые будут использоваться для первоначального построения набора. Дополнительные методы предоставляются для добавления тестовых примеров и наборов в коллекцию позже.10721073Объекты [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) во многом аналогичны объектам [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), за исключением того, что они не реализуют тест напрямую. Вместо этого они служат для объединения тестов в группы, которые должны выполняться совместно. Есть несколько дополнительных методов для добавления тестов в экземпляры [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite):10741075#### `addTest(test)`10761077Добавляет объект [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) в набор.10781079#### `addTests(tests)`10801081Добавляет все тесты из итерируемого объекта, содержащего экземпляры [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) и [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite), в данный тестовый набор.10821083Это эквивалентно перебору *tests* с вызовом [`addTest()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite.addTest) для каждого элемента.10841085[`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) имеет общие следующие методы с [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase):10861087#### `run(result)`10881089Запускает тесты, связанные с этим набором, собирая результат в объект результата теста, переданный как *result*. Обратите внимание, что, в отличие от [`TestCase.run()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase.run), [`TestSuite.run()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite.run) требует обязательной передачи объекта результата.10901091#### `debug()`10921093Запускает тесты, связанные с этим набором, без сбора результата. Это позволяет исключениям, возбуждённым тестом, распространяться до вызывающего кода и может использоваться для поддержки запуска тестов под отладчиком.10941095#### `countTestCases()`10961097Возвращает количество тестов, представленных этим тестовым объектом, включая все отдельные тесты и поднаборы.10981099#### `__iter__()`11001101Тесты, сгруппированные в [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite), всегда извлекаются через итерацию. Подклассы могут предоставлять тесты лениво, переопределяя [`__iter__()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite.__iter__). Обратите внимание, что этот метод может вызываться несколько раз для одного набора (например, при подсчёте тестов или сравнении на равенство) поэтому на всех повторных итерациях должны возвращаться одни и те же тесты.11021103Изменено в версии 3.2: В более ранних версиях [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) обращался к тестам напрямую, а не через итерацию, поэтому переопределение [`__iter__()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite.__iter__) было недостаточно для предоставления тестов.11041105В типичном использовании объекта [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) метод [`run()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite.run) вызывается `TestRunner`, а не тестовым стендом конечного пользователя.11061107### 25.3.7.3. Загрузка и запуск тестов11081109#### `class unittest.TestLoader`11101111Класс [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader) используется для создания тестовых наборов из классов и модулей. Обычно нет необходимости создавать экземпляр этого класса; модуль [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest) предоставляет экземпляр, который может использоваться совместно как [`unittest.defaultTestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.defaultTestLoader). Однако использование подкласса или экземпляра позволяет настраивать некоторые конфигурируемые свойства.11121113Объекты [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader) имеют следующие методы:11141115#### `loadTestsFromTestCase(testCaseClass)`11161117Возвращает набор всех тестовых случаев, содержащихся в классе `testCaseClass`, производном от [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase).11181119#### `loadTestsFromModule(module)`11201121Возвращает набор всех тестовых случаев, содержащихся в данном модуле. Этот метод ищет в *module* классы, производные от [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), и создает экземпляр класса для каждого тестового метода, определенного в классе.11221123> **Примечание**1124>1125> Хотя использование иерархии классов, производных от [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), может быть удобным для совместного использования фикстур и вспомогательных функций, определение тестовых методов в базовых классах, которые не предназначены для прямого инстанцирования, плохо сочетается с этим методом. Однако это может быть полезно, когда фикстуры различаются и определяются в подклассах.11261127Если модуль предоставляет функцию `load_tests`, она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это [протокол load\_tests](https://python-all.ru/3.2/library/unittest.html#load-tests-protocol).11281129Изменено в версии 3.2: Добавлена поддержка `load_tests`.11301131#### `loadTestsFromName(name, module=None)`11321133Возвращает набор всех тестовых случаев по строковому спецификатору.11341135Спецификатор *name* – это «точечное имя», которое может разрешаться в модуль, класс тестового случая, тестовый метод внутри класса тестового случая, экземпляр [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) или вызываемый объект, возвращающий экземпляр [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite). Эти проверки применяются в указанном порядке; то есть метод в классе возможного тестового случая будет распознан как «тестовый метод внутри класса тестового случая», а не как «вызываемый объект».11361137Например, если у вас есть модуль `SampleTests`, содержащий класс `SampleTestCase`, производный от [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), с тремя тестовыми методами (`test_one()`, `test_two()` и `test_three()`), то спецификатор `'SampleTests.SampleTestCase'` приведет к тому, что этот метод вернет набор, который запустит все три тестовых метода. Использование спецификатора `'SampleTests.SampleTestCase.test_two'` приведет к возврату тестового набора, который запустит только тестовый метод `test_two()`. Спецификатор может ссылаться на модули и пакеты, которые еще не были импортированы; они будут импортированы как побочный эффект.11381139Метод опционально разрешает *name* относительно заданного *module*.11401141#### `loadTestsFromNames(names, module=None)`11421143Аналогично [`loadTestsFromName()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader.loadTestsFromName), но принимает последовательность имён, а не одно имя. Возвращаемое значение – тестовый набор, содержащий все тесты, определённые для каждого имени.11441145#### `getTestCaseNames(testCaseClass)`11461147Возвращает отсортированную последовательность имён методов, найденных в *testCaseClass*; и он должен быть [подклассом `TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase).11481149#### `discover(start_dir, pattern='test*.py', top_level_dir=None)`11501151Находит и возвращает все тестовые модули из указанного начального каталога, рекурсивно обходя подкаталоги для их поиска. Будут загружены только тестовые файлы, соответствующие *pattern*. (Используется сопоставление с шаблоном в стиле оболочки.) Только имена модулей, которые импортируемы (т.е. являются корректными идентификаторами Python), будут загружены.11521153Все тестовые модули должны быть импортируемыми из корневого каталога проекта. Если стартовый каталог не является корневым, то корневой каталог необходимо указать отдельно.11541155Если импорт модуля завершается неудачей, например из-за синтаксической ошибки, то это будет записано как одна ошибка, и обнаружение продолжится.11561157Если имя тестового пакета (каталог с `__init__.py`) соответствует шаблону, то в пакете будет проверено наличие функции `load_tests`. Если она существует, то она будет вызвана с аргументами *loader*, *tests*, *pattern*.11581159Если функция load\_tests существует, то обнаружение *не* выполняет рекурсивный обход пакета, `load_tests` отвечает за загрузку всех тестов в пакете.11601161Шаблон намеренно не хранится как атрибут загрузчика, чтобы пакеты могли продолжать поиск самостоятельно. *top\_level\_dir* хранится, чтобы `load_tests` не нужно было передавать этот аргумент в `loader.discover()`.11621163*start\_dir* может быть как точечным именем модуля, так и каталогом.11641165Новое в версии 3.2.11661167Следующие атрибуты [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader) можно настроить либо через создание подкласса, либо присваиванием экземпляру:11681169#### `testMethodPrefix`11701171Строка, задающая префикс имён методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию – `'test'`.11721173Это влияет на [`getTestCaseNames()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader.getTestCaseNames) и все методы `loadTestsFrom*()`.11741175#### `sortTestMethodsUsing`11761177Функция, используемая для сравнения имён методов при сортировке в [`getTestCaseNames()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader.getTestCaseNames) и во всех методах `loadTestsFrom*()`.11781179#### `suiteClass`11801181Вызываемый объект, который создаёт тестовый набор из списка тестов. Никакие методы результирующего объекта не требуются. Значение по умолчанию – класс [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite).11821183Это влияет на все методы `loadTestsFrom*()`.11841185#### `class unittest.TestResult`11861187Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие завершились неудачей.11881189Объект [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult) хранит результаты набора тестов. Классы [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) и [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) обеспечивают корректную запись результатов; авторам тестов не нужно заботиться о записи результатов тестов.11901191Тестовые фреймворки, построенные на основе [`unittest`](https://python-all.ru/3.2/library/unittest.html#module-unittest), могут нуждаться в доступе к объекту [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult), создаваемому при выполнении набора тестов для целей отчётности; экземпляр [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult) возвращается методом `TestRunner.run()` для этой цели.11921193Экземпляры [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult) имеют следующие атрибуты, которые будут интересны при просмотре результатов выполнения набора тестов:11941195#### `errors`11961197Список, содержащий кортежи из двух элементов: экземпляры [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) и строки с форматированными трассировками. Каждый кортеж представляет тест, вызвавший неожиданное исключение.11981199#### `failures`12001201Список, содержащий кортежи из двух элементов: экземпляров [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) и строк с отформатированными трассировками. Каждый кортеж представляет тест, в котором сбой был явно зафиксирован с помощью методов `TestCase.fail*()` или `TestCase.assert*()`.12021203#### `skipped`12041205Список, содержащий кортежи из двух элементов: экземпляры [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) и строки с причиной пропуска теста.12061207Новое в версии 3.1.12081209#### `expectedFailures`12101211Список, содержащий кортежи из двух элементов: экземпляры [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) и строки с форматированными трассировками. Каждый кортеж представляет ожидаемую ошибку тестового случая.12121213#### `unexpectedSuccesses`12141215Список, содержащий экземпляры [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), которые были отмечены как ожидаемые ошибки, но прошли успешно.12161217#### `shouldStop`12181219Устанавливается в `True`, когда выполнение тестов должно быть остановлено вызовом [`stop()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.stop).12201221#### `testsRun`12221223Общее количество запущенных на данный момент тестов.12241225#### `buffer`12261227Если установлено в true, `sys.stdout` и `sys.stderr` будут буферизироваться между вызовами [`startTest()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.startTest) и [`stopTest()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.stopTest). Собранный вывод будет выводиться в настоящие `sys.stdout` и `sys.stderr` только если тест завершается неудачей или ошибкой. Любой вывод также присоединяется к сообщению об ошибке или сбое.12281229Новое в версии 3.2.12301231#### `failfast`12321233Если установлено в true, [`stop()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.stop) будет вызван при первой неудаче или ошибке, останавливая выполнение тестов.12341235Новое в версии 3.2.12361237#### `wasSuccessful()`12381239Возвращает `True`, если все выполненные на данный момент тесты прошли, иначе возвращает `False`.12401241#### `stop()`12421243Этот метод может быть вызван, чтобы сигнализировать, что выполняемый набор тестов должен быть прерван установкой атрибута [`shouldStop`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.shouldStop) в `True`. Объекты `TestRunner` должны учитывать этот флаг и возвращаться без выполнения дополнительных тестов.12441245Например, эта возможность используется классом [`TextTestRunner`](https://python-all.ru/3.2/library/unittest.html#unittest.TextTestRunner) для остановки тестового фреймворка, когда пользователь подает сигнал прерывания с клавиатуры. Интерактивные инструменты, предоставляющие реализации `TestRunner`, могут использовать это аналогичным образом.12461247Следующие методы класса [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult) используются для поддержки внутренних структур данных и могут быть расширены в подклассах для поддержки дополнительных требований к отчетности. Это особенно полезно при создании инструментов, поддерживающих интерактивную отчетность во время выполнения тестов.12481249#### `startTest(test)`12501251Вызывается перед запуском тестового сценария *test*.12521253#### `stopTest(test)`12541255Вызывается после выполнения тестового сценария *test*, независимо от результата.12561257#### `startTestRun(test)`12581259Вызывается один раз перед выполнением любых тестов.12601261Новое в версии 3.1.12621263#### `stopTestRun(test)`12641265Вызывается один раз после выполнения всех тестов.12661267Новое в версии 3.1.12681269#### `addError(test, err)`12701271Вызывается, когда тестовый сценарий *test* вызывает неожиданное исключение. *err* – это кортеж в формате, возвращаемом [`sys.exc_info()`](https://python-all.ru/3.2/library/sys.html#sys.exc_info): `(type, value, traceback)`.12721273Реализация по умолчанию добавляет кортеж `(test, formatted_err)` в атрибут [`errors`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.errors) экземпляра, где *formatted\_err* – это форматированная трассировка, полученная из *err*.12741275#### `addFailure(test, err)`12761277Вызывается, когда тестовый пример *test* сигнализирует о неудаче. *err* – это кортеж в формате, возвращаемом [`sys.exc_info()`](https://python-all.ru/3.2/library/sys.html#sys.exc_info): `(type, value, traceback)`.12781279Реализация по умолчанию добавляет кортеж `(test, formatted_err)` в атрибут [`failures`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.failures) экземпляра, где *formatted\_err* – это форматированная трассировка, полученная из *err*.12801281#### `addSuccess(test)`12821283Вызывается, когда тестовый сценарий *test* завершается успешно.12841285Реализация по умолчанию ничего не делает.12861287#### `addSkip(test, reason)`12881289Вызывается, когда тестовый сценарий *test* пропускается. *reason* – причина, которую тест указал для пропуска.12901291Реализация по умолчанию добавляет кортеж `(test, reason)` в атрибут [`skipped`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.skipped) экземпляра.12921293#### `addExpectedFailure(test, err)`12941295Вызывается, когда тестовый пример *test* завершается неудачей, но был помечен декоратором [`expectedFailure()`](https://python-all.ru/3.2/library/unittest.html#unittest.expectedFailure).12961297Реализация по умолчанию добавляет кортеж `(test, formatted_err)` в атрибут [`expectedFailures`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.expectedFailures) экземпляра, где *formatted\_err* – это форматированная трассировка, полученная из *err*.12981299#### `addUnexpectedSuccess(test)`13001301Вызывается, когда тестовый пример *test* был помечен декоратором [`expectedFailure()`](https://python-all.ru/3.2/library/unittest.html#unittest.expectedFailure), но завершился успешно.13021303Реализация по умолчанию добавляет тест в атрибут [`unexpectedSuccesses`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.unexpectedSuccesses) экземпляра.13041305#### `class unittest.TextTestResult(stream, descriptions, verbosity)`13061307Конкретная реализация [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult), используемая [`TextTestRunner`](https://python-all.ru/3.2/library/unittest.html#unittest.TextTestRunner).13081309Новое в версии 3.2: Ранее этот класс назывался `_TextTestResult`. Старое имя всё ещё существует как псевдоним, но устарело.13101311#### `unittest.defaultTestLoader`13121313Экземпляр класса [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader), предназначенный для совместного использования. Если настройка [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader) не требуется, можно использовать этот экземпляр вместо многократного создания новых.13141315#### `class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, runnerclass=None, warnings=None)`13161317Базовая реализация средства запуска тестов, которая выводит результаты в поток данных. Если *stream* равен `None` (по умолчанию), в качестве выходного потока данных используется [`sys.stderr`](https://python-all.ru/3.2/library/sys.html#sys.stderr). Этот класс имеет несколько настраиваемых параметров, но в целом очень прост. Графические приложения, которые запускают наборы тестов, должны предоставлять альтернативные реализации.13181319По умолчанию этот исполнитель показывает [`DeprecationWarning`](https://python-all.ru/3.2/library/exceptions.html#DeprecationWarning), [`PendingDeprecationWarning`](https://python-all.ru/3.2/library/exceptions.html#PendingDeprecationWarning) и [`ImportWarning`](https://python-all.ru/3.2/library/exceptions.html#ImportWarning), даже если они [*по умолчанию игнорируются*](https://python-all.ru/3.2/library/warnings.html#warning-ignored). Предупреждения об устаревании, вызванные [*устаревшими методами unittest*](https://python-all.ru/3.2/library/unittest.html#deprecated-aliases), также обрабатываются особым образом: когда фильтры предупреждений равны `'default'` или `'always'`, они будут появляться только один раз на модуль, чтобы избежать слишком большого количества сообщений предупреждений. Это поведение можно переопределить с помощью параметров *-Wd* или *-Wa* и оставив *warnings* равным `None`.13201321Изменено в версии 3.2: Добавлен аргумент `warnings`.13221323Изменено в версии 3.2: Поток по умолчанию устанавливается в [`sys.stderr`](https://python-all.ru/3.2/library/sys.html#sys.stderr) во время создания экземпляра, а не во время импорта.13241325#### `_makeResult()`13261327Этот метод возвращает экземпляр `TestResult`, используемый `run()`. Он не предназначен для прямого вызова, но может быть переопределён в подклассах для предоставления собственного `TestResult`.13281329`_makeResult()` создаёт экземпляр класса или вызываемого объекта, переданного в конструктор `TextTestRunner` в качестве аргумента `resultclass`. По умолчанию используется [`TextTestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TextTestResult), если `resultclass` не предоставлен. Класс результата создаётся со следующими аргументами:13301331```python1332stream, descriptions, verbosity1333```13341335#### `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)`13361337Программа командной строки, которая загружает набор тестов из *module* и запускает их; это в первую очередь для удобного выполнения тестовых модулей. Простейший способ использования этой функции – добавить следующую строку в конец тестового скрипта:13381339```python1340if __name__ == '__main__':1341 unittest.main()1342```13431344Можно запускать тесты с более подробной информацией, передав аргумент verbosity:13451346```python1347if __name__ == '__main__':1348 unittest.main(verbosity=2)1349```13501351Аргумент *argv* может быть списком параметров, переданных программе, где первый элемент – имя программы. Если он не указан или равен `None`, используются значения [`sys.argv`](https://python-all.ru/3.2/library/sys.html#sys.argv).13521353Аргумент *testRunner* может быть либо классом средства запуска тестов, либо уже созданным экземпляром такого класса. По умолчанию `main` вызывает [`sys.exit()`](https://python-all.ru/3.2/library/sys.html#sys.exit) с кодом возврата, указывающим на успех или неудачу выполнения тестов.13541355Аргумент *testLoader* должен быть экземпляром [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader), по умолчанию используется [`defaultTestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.defaultTestLoader).13561357`main` поддерживает использование из интерактивного интерпретатора путём передачи аргумента `exit=False`. При этом результат выводится на стандартный вывод без вызова [`sys.exit()`](https://python-all.ru/3.2/library/sys.html#sys.exit):13581359```python1360>>> from unittest import main1361>>> main(module='test_module', exit=False)1362```13631364Параметры *failfast*, *catchbreak* и *buffer* имеют тот же эффект, что и одноимённые [параметры командной строки](https://python-all.ru/3.2/library/unittest.html#command-line-options).13651366Аргумент *warning* задаёт [*фильтр предупреждений*](https://python-all.ru/3.2/library/warnings.html#warning-filter), который следует использовать во время выполнения тестов. Если он не указан, он останется равным `None`, если опция *-W* передана **python**, в противном случае он будет установлен в `'default'`.13671368Вызов `main` на самом деле возвращает экземпляр класса `TestProgram`. Результат выполнения тестов сохраняется в атрибуте `result`.13691370Изменено в версии 3.1: Был добавлен параметр *exit*.13711372Изменено в версии 3.2: Были добавлены параметры *verbosity*, *failfast*, *catchbreak*, *buffer* и *warnings*.13731374#### 25.3.7.3.1. load\_tests Протокол13751376Новое в версии 3.2.13771378Модули или пакеты могут настраивать загрузку тестов из себя во время обычного запуска тестов или обнаружения тестов, реализуя функцию с именем `load_tests`.13791380Если тестовый модуль определяет `load_tests`, он будет вызван [`TestLoader.loadTestsFromModule()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader.loadTestsFromModule) со следующими аргументами:13811382```python1383load_tests(loader, standard_tests, None)1384```13851386Она должна возвращать [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite).13871388*loader* – это экземпляр [`TestLoader`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader), который выполняет загрузку. *standard\_tests* – это тесты, которые загружаются по умолчанию из модуля. Обычно тестовые модули хотят только добавить или удалить тесты из стандартного набора. Третий аргумент используется при загрузке пакетов в ходе обнаружения тестов.13891390Типичная функция `load_tests`, которая загружает тесты из определённого набора классов [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase), может выглядеть так:13911392```python1393test_cases = (TestCase1, TestCase2, TestCase3)13941395def load_tests(loader, tests, pattern):1396 suite = TestSuite()1397 for test_class in test_cases:1398 tests = loader.loadTestsFromTestCase(test_class)1399 suite.addTests(tests)1400 return suite1401```14021403Если запущено обнаружение (из командной строки или вызовом [`TestLoader.discover()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestLoader.discover)) с шаблоном, соответствующим имени пакета, то в пакете `__init__.py` будет проверено наличие `load_tests`.14041405> **Примечание**1406>1407> Шаблон по умолчанию – `'test*.py'`. Он соответствует всем Python-файлам, начинающимся с `'test'`, но *не* соответствует тестовым каталогам.1408>1409> Шаблон вида `'test*'` будет соответствовать как тестовым пакетам, так и модулям.14101411Если в пакете `__init__.py` определена `load_tests`, то она будет вызвана, и обнаружение в пакете не продолжится. `load_tests` вызывается со следующими аргументами:14121413```python1414load_tests(loader, standard_tests, pattern)1415```14161417Она должна вернуть [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite), представляющий все тесты из пакета. (`standard_tests` будет содержать только тесты, собранные из `__init__.py`.)14181419Поскольку шаблон передаётся в `load_tests`, пакет может продолжить (и, возможно, изменить) обнаружение тестов. Функция `load_tests`, которая «ничего не делает» для тестового пакета, будет выглядеть так:14201421```python1422def load_tests(loader, standard_tests, pattern):1423 # корневой каталог, кэшированный на экземпляре загрузчика1424 this_dir = os.path.dirname(__file__)1425 package_tests = loader.discover(start_dir=this_dir, pattern=pattern)1426 standard_tests.addTests(package_tests)1427 return standard_tests1428```14291430## 25.3.8. Фикстуры классов и модулей14311432Фикстуры уровня класса и модуля реализованы в [`TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite). Когда тестовый набор встречает тест из нового класса, вызывается `tearDownClass()` из предыдущего класса (если он есть), а затем `setUpClass()` из нового класса.14331434Аналогично, если тест из другого модуля, отличного от предыдущего, то выполняется `tearDownModule` из предыдущего модуля, а затем `setUpModule` из нового модуля.14351436После выполнения всех тестов запускаются финальные `tearDownClass` и `tearDownModule`.14371438Обратите внимание, что общие фикстуры плохо совместимы с такими возможностями, как параллельное выполнение тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.14391440Порядок тестов по умолчанию, создаваемый загрузчиками тестов unittest, группирует все тесты из одних и тех же модулей и классов вместе. Это приводит к тому, что `setUpClass` / `setUpModule` (и т.д.) вызываются ровно один раз для каждого класса и модуля. Если перемешать порядок так, чтобы тесты из разных модулей и классов оказались рядом, эти общие функции фикстур могут быть вызваны несколько раз в одном запуске тестов.14411442Общие фикстуры не предназначены для работы с наборами, имеющими нестандартный порядок. `BaseTestSuite` по-прежнему существует для фреймворков, которые не хотят поддерживать общие фикстуры.14431444Если в одной из общих функций фикстур возникает исключение, тест отмечается как ошибочный. Поскольку соответствующего экземпляра теста нет, создаётся объект `_ErrorHolder` (с тем же интерфейсом, что и у [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase)) для представления ошибки. Если используется стандартный исполнитель тестов unittest, эта деталь не имеет значения, но для авторов фреймворков она может быть актуальной.14451446### 25.3.8.1. setUpClass и tearDownClass14471448Они должны быть реализованы как методы класса:14491450```python1451import unittest14521453class Test(unittest.TestCase):1454 @classmethod1455 def setUpClass(cls):1456 cls._connection = createExpensiveConnectionObject()14571458 @classmethod1459 def tearDownClass(cls):1460 cls._connection.destroy()1461```14621463Если нужно, чтобы `setUpClass` и `tearDownClass` в базовых классах вызывались, то их необходимо вызывать явно. Реализации в [`TestCase`](https://python-all.ru/3.2/library/unittest.html#unittest.TestCase) пусты.14641465Если во время `setUpClass` возникает исключение, тесты в классе не выполняются, и `tearDownClass` не вызывается. Пропущенные классы не будут иметь выполненных `setUpClass` или `tearDownClass`. Если исключение – это [`SkipTest`](https://python-all.ru/3.2/library/unittest.html#unittest.SkipTest), то класс будет отмечен как пропущенный, а не как ошибочный.14661467### 25.3.8.2. setUpModule и tearDownModule14681469Их следует реализовывать как функции:14701471```python1472def setUpModule():1473 createConnection()14741475def tearDownModule():1476 closeConnection()1477```14781479Если в `setUpModule` возникает исключение, ни один из тестов в модуле не будет выполнен, и `tearDownModule` не будет вызван. Если исключение – это [`SkipTest`](https://python-all.ru/3.2/library/unittest.html#unittest.SkipTest), то модуль будет отмечен как пропущенный, а не как ошибочный.14801481## 25.3.9. Обработка сигналов14821483Новое в версии 3.2.14841485Параметр командной строки [*-c/--catch*](https://python-all.ru/3.2/library/unittest.html#cmdoption-unittest-c) для unittest, а также параметр `catchbreak` для [`unittest.main()`](https://python-all.ru/3.2/library/unittest.html#unittest.main), обеспечивают более удобную обработку Ctrl+C во время запуска тестов. При включённом поведении перехвата Ctrl+C позволяет завершиться текущему выполняющемуся тесту, а затем выполнение тестов завершается и выводятся все результаты на данный момент. Повторное нажатие Ctrl+C вызовет [`KeyboardInterrupt`](https://python-all.ru/3.2/library/exceptions.html#KeyboardInterrupt) обычным образом.14861487Обработчик сигнала Ctrl+C пытается оставаться совместимым с кодом или тестами, которые устанавливают свой собственный обработчик `signal.SIGINT`. Если вызывается обработчик `unittest`, но он *не является* установленным обработчиком `signal.SIGINT`, т.е. он был заменён тестируемой системой и делегирован ей, то вызывается обработчик по умолчанию. Обычно это ожидаемое поведение для кода, который заменяет установленный обработчик и делегирует ему. Для отдельных тестов, которым требуется отключить обработку Ctrl+C в `unittest`, можно использовать декоратор [`removeHandler()`](https://python-all.ru/3.2/library/unittest.html#unittest.removeHandler).14881489Существует несколько вспомогательных функций для разработчиков фреймворков, позволяющих включить обработку control-c в тестовых фреймворках.14901491#### `unittest.installHandler()`14921493Устанавливает обработчик Ctrl+C. При получении `signal.SIGINT` (обычно в ответ на нажатие пользователем Ctrl+C) у всех зарегистрированных результатов вызывается [`stop()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.stop).14941495#### `unittest.registerResult(result)`14961497Регистрирует объект [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult) для обработки Ctrl+C. Регистрация результата сохраняет слабую ссылку на него, поэтому это не мешает сборщику мусора удалить результат.14981499Регистрация объекта [`TestResult`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult) не имеет побочных эффектов, если обработка Ctrl+C не включена, поэтому тестовые фреймворки могут безоговорочно регистрировать все создаваемые ими результаты независимо от того, включена ли обработка.15001501#### `unittest.removeResult(result)`15021503Удаляет зарегистрированный результат. После удаления результата [`stop()`](https://python-all.ru/3.2/library/unittest.html#unittest.TestResult.stop) больше не будет вызываться для этого объекта результата в ответ на Ctrl+C.15041505#### `unittest.removeHandler(function=None)`15061507При вызове без аргументов эта функция удаляет обработчик сочетания клавиш Control-C, если он был установлен. Эту функцию также можно использовать как декоратор теста, чтобы временно удалить обработчик на время выполнения теста:15081509```python1510@unittest.removeHandler1511def test_signal_handling(self):1512 ...1513```1514