Документация Python неофициальный перевод

unittest.md

1233 строк · 96.2 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.1/library/unittest.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 25.3. `unittest` – фреймворк для модульного тестирования89(Если вы уже знакомы с основными понятиями тестирования, можете перейти к [*списку методов assert*](https://python-all.ru/3.1/library/unittest.html#assert-methods).)1011Среда модульного тестирования Python, иногда называемая «PyUnit», является реализацией JUnit на языке Python, созданной Кентом Беком и Эрихом Гаммой. JUnit, в свою очередь, представляет собой Java-версию среды тестирования Smalltalk Кента Бека. Каждая из них является фактическим стандартом модульного тестирования для своего языка.1213`unittest` поддерживает автоматизацию тестирования, совместное использование кода настройки и завершения для тестов, объединение тестов в коллекции и независимость тестов от фреймворка отчетности. Модуль `unittest` предоставляет классы, которые упрощают поддержку этих качеств для набора тестов.1415Для этого `unittest` поддерживает несколько важных концепций:1617**тестовая фикстура**1819*Тестовая фикстура*2021представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, и любые сопутствующие действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск серверного процесса.2223**тестовый случай**2425*Тестовый пример*2627– это наименьшая единица тестирования. Он проверяет определенную реакцию на конкретный набор входных данных.2829`unittest`3031предоставляет базовый класс3233[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)3435, который можно использовать для создания новых тестовых примеров.3637**набор тестов**3839*Набор тестов*4041– это совокупность тестовых случаев, наборов тестов или и того, и другого. Он используется для объединения тестов, которые должны выполняться вместе.4243**исполнитель тестов**4445*Исполнитель тестов*4647– это компонент, который управляет выполнением тестов и предоставляет результат пользователю. Исполнитель может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение, указывающее на результаты выполнения тестов.4849Концепции тестового примера и тестовой фикстуры поддерживаются через классы [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) и [`FunctionTestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.FunctionTestCase); первый следует использовать при создании новых тестов, а второй можно использовать при интеграции существующего тестового кода с фреймворком на основе `unittest`. При построении тестовых фикстур с помощью [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) можно переопределить методы [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp) и [`tearDown()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.tearDown) для инициализации и очистки фикстуры. С помощью [`FunctionTestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.FunctionTestCase) можно передать существующие функции в конструктор для этих целей. Когда тест запускается, сначала выполняется инициализация фикстуры; если она успешна, то после выполнения теста запускается метод очистки, независимо от результата теста. Каждый экземпляр [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) будет использоваться только для выполнения одного метода теста, поэтому для каждого теста создается новая фикстура.5051Тестовые наборы реализуются классом [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite). Этот класс позволяет объединять отдельные тесты и тестовые наборы; при выполнении набора запускаются все тесты, добавленные непосредственно в набор и в «дочерние» тестовые наборы.5253Исполнитель тестов – это объект, который предоставляет единственный метод `run()`, принимающий объект [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) в качестве параметра и возвращающий объект результата. Класс [`TestResult`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult) предоставляется для использования в качестве объекта результата. `unittest` предоставляет [`TextTestRunner`](https://python-all.ru/3.1/library/unittest.html#unittest.TextTestRunner) в качестве примера исполнителя тестов, который по умолчанию выводит результаты тестов в поток стандартных ошибок. Альтернативные исполнители могут быть реализованы для других сред (например, графических) без необходимости наследования от какого-либо конкретного класса.5455> **См. также**56>57> **Модуль [`doctest`](https://python-all.ru/3.1/library/doctest.html#module-doctest)**58>59> Ещё один модуль поддержки тестирования с совершенно другим подходом.60>61> **[unittest2: обратный порт новых возможностей unittest для Python 2.4–2.6](https://python-all.ru/3.1/library/unittest.html)**62>63> В Python 2.7 в unittest было добавлено много новых возможностей, включая обнаружение тестов. unittest2 позволяет использовать эти возможности в более ранних версиях Python.64>65> **[Простое тестирование в Smalltalk: с шаблонами](https://python-all.ru/3.1/library/unittest.html)**66>67> Оригинальная статья Кента Бека о фреймворках тестирования, использующих шаблон, общий с68>69> `unittest`70>71> .72>73> **[Nose](https://python-all.ru/3.1/library/unittest.html) и [py.test](https://python-all.ru/3.1/library/unittest.html)**74>75> Сторонние фреймворки unittest с более лёгким синтаксисом для написания тестов. Например,76>77> `assert func(10) == 42`78>79> .80>81> **[Таксономия инструментов тестирования Python](https://python-all.ru/3.1/library/unittest.html)**82>83> Обширный список инструментов тестирования Python, включая фреймворки функционального тестирования и библиотеки имитационных объектов (mock).84>85> **[Список рассылки по тестированию в Python](https://python-all.ru/3.1/library/unittest.html)**86>87> Группа по интересам для обсуждения тестирования и инструментов тестирования в Python.8889## 25.3.1. Простой пример9091Модуль `unittest` предоставляет богатый набор инструментов для создания и запуска тестов. В этом разделе показано, что небольшого подмножества инструментов достаточно для удовлетворения потребностей большинства пользователей.9293Вот короткий скрипт для тестирования трёх функций из модуля [`random`](https://python-all.ru/3.1/library/random.html#module-random):9495```python96import random97import unittest9899class TestSequenceFunctions(unittest.TestCase):100101    def setUp(self):102        self.seq = list(range(10))103104    def test_shuffle(self):105        # проверить, что перемешанная последовательность не теряет ни одного элемента106        random.shuffle(self.seq)107        self.seq.sort()108        self.assertEqual(self.seq, list(range(10)))109110        # должно вызывать исключение для неизменяемой последовательности111        self.assertRaises(TypeError, random.shuffle, (1,2,3))112113    def test_choice(self):114        element = random.choice(self.seq)115        self.assertTrue(element in self.seq)116117    def test_sample(self):118        with self.assertRaises(ValueError):119            random.sample(self.seq, 20)120        for element in random.sample(self.seq, 5):121            self.assertTrue(element in self.seq)122123if __name__ == '__main__':124    unittest.main()125```126127Тестовый пример создаётся путём создания подкласса [`unittest.TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase). Три отдельных теста определяются методами, имена которых начинаются с букв `test`. Это соглашение об именах сообщает программе запуска тестов, какие методы представляют собой тесты.128129Суть каждого теста сводится к вызову [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual) для проверки ожидаемого результата; [`assertTrue()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertTrue) – для проверки условия; или [`assertRaises()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRaises) – чтобы убедиться, что возникает ожидаемое исключение. Эти методы используются вместо оператора [`assert`](https://python-all.ru/3.1/reference/simple_stmts.html#assert), чтобы средство запуска тестов могло накапливать все результаты и формировать отчёт.130131Если определён метод [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp), средство запуска тестов выполнит его перед каждым тестом. Аналогично, если определён метод [`tearDown()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.tearDown), средство запуска тестов вызовет его после каждого теста. В примере [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp) использовался для создания новой последовательности для каждого теста.132133Последний блок демонстрирует простой способ запуска тестов. [`unittest.main()`](https://python-all.ru/3.1/library/unittest.html#unittest.main) предоставляет интерфейс командной строки для тестового скрипта. При запуске из командной строки указанный скрипт выдаёт вывод, который выглядит так:134135```python136...137----------------------------------------------------------------------138Ran 3 tests in 0.000s139140OK141```142143Вместо [`unittest.main()`](https://python-all.ru/3.1/library/unittest.html#unittest.main) существуют другие способы запуска тестов с более точным контролем, менее лаконичным выводом и без необходимости запуска из командной строки. Например, последние две строки можно заменить на:144145```python146suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)147unittest.TextTestRunner(verbosity=2).run(suite)148```149150Запуск изменённого скрипта из интерпретатора или другого скрипта приводит к следующему выводу:151152```python153test_choice (__main__.TestSequenceFunctions) ... ok154test_sample (__main__.TestSequenceFunctions) ... ok155test_shuffle (__main__.TestSequenceFunctions) ... ok156157----------------------------------------------------------------------158Ran 3 tests in 0.110s159160OK161```162163Приведенные выше примеры демонстрируют наиболее часто используемые возможности `unittest`, которых достаточно для многих повседневных задач тестирования. Остальная часть документации исследует полный набор возможностей с нуля.164165## 25.3.2. Интерфейс командной строки166167Модуль unittest можно использовать из командной строки для запуска тестов из модулей, классов или даже отдельных тестовых методов:168169```python170python -m unittest test_module1 test_module2171python -m unittest test_module.TestClass172python -m unittest test_module.TestClass.test_method173```174175Можно передать список с любой комбинацией имён модулей, а также полных имён классов или методов.176177Можно запускать тесты с большей детализацией (повышенной подробностью), передав флаг -v:178179```python180python -m unittest -v test_module181```182183Чтобы получить список всех параметров командной строки:184185```python186python -m unittest -h187```188189## 25.3.3. Организация тестового кода190191Основными строительными блоками модульного тестирования являются *тестовые примеры* – отдельные сценарии, которые необходимо настроить и проверить на корректность. В `unittest` тестовые примеры представлены экземплярами класса `unittest`::[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase). Чтобы создать собственные тестовые примеры, нужно написать подклассы [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) или использовать [`FunctionTestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.FunctionTestCase).192193Экземпляр класса, производного от [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase), представляет собой объект, который может полностью выполнить один тестовый метод вместе с необязательным кодом настройки и очистки.194195Тестовый код экземпляра [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) должен быть полностью самодостаточным, чтобы его можно было запускать как изолированно, так и в произвольной комбинации с любым количеством других тестовых сценариев.196197Простейший подкласс [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) просто переопределяет метод `runTest()`, чтобы выполнить конкретный тестовый код:198199```python200import unittest201202class DefaultWidgetSizeTestCase(unittest.TestCase):203    def runTest(self):204        widget = Widget('The widget')205        self.assertEqual(widget.size(), (50, 50), 'incorrect default size')206```207208Обратите внимание, что для проверки чего-либо используются методы `assert*()` из базового класса [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase). Если тест проваливается, возникает исключение, и `unittest` идентифицирует тестовый пример как *неудачу*. Любые другие исключения будут расцениваться как *ошибки*. Это помогает определить, в чем проблема: *неудачи* вызваны неверными результатами – например, получено 5 вместо ожидаемой 6. *Ошибки* вызваны неверным кодом – например, [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError) из-за неправильного вызова функции.209210Способ запуска тестового примера будет описан позже. Пока обратите внимание, что для создания экземпляра такого тестового примера мы вызываем его конструктор без аргументов:211212```python213testCase = DefaultWidgetSizeTestCase()214```215216Теперь таких тестовых примеров может быть много, и их настройка может повторяться. В приведённом выше случае создание `Widget` в каждом из 100 подклассов тестовых примеров Widget привело бы к некрасивому дублированию.217218К счастью, такой код настройки можно вынести, реализовав метод [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp), который тестовый фреймворк автоматически вызовет при запуске теста:219220```python221import unittest222223class SimpleWidgetTestCase(unittest.TestCase):224    def setUp(self):225        self.widget = Widget('The widget')226227class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):228    def runTest(self):229        self.assertEqual(self.widget.size(), (50,50),230                         'incorrect default size')231232class WidgetResizeTestCase(SimpleWidgetTestCase):233    def runTest(self):234        self.widget.resize(100,150)235        self.assertEqual(self.widget.size(), (100,150),236                         'wrong size after resize')237```238239Если метод [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp) возбуждает исключение во время выполнения теста, фреймворк считает, что в тесте произошла ошибка, и метод `runTest()` не будет выполнен.240241Аналогично можно предоставить метод [`tearDown()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.tearDown), который выполняет очистку после выполнения метода `runTest()`:242243```python244import unittest245246class SimpleWidgetTestCase(unittest.TestCase):247    def setUp(self):248        self.widget = Widget('The widget')249250    def tearDown(self):251        self.widget.dispose()252        self.widget = None253```254255Если [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp) выполнился успешно, метод [`tearDown()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.tearDown) будет запущен независимо от того, успешно ли выполнился `runTest()`.256257Такое рабочее окружение для тестового кода называется *фикстурой*.258259Часто много маленьких тестовых примеров используют одну и ту же фикстуру. В этом случае пришлось бы создавать подклассы `SimpleWidgetTestCase` для множества маленьких классов с одним методом, таких как `DefaultWidgetSizeTestCase`. Это отнимает много времени и обескураживает, поэтому, следуя примеру JUnit, `unittest` предоставляет более простой механизм:260261```python262import unittest263264class WidgetTestCase(unittest.TestCase):265    def setUp(self):266        self.widget = Widget('The widget')267268    def tearDown(self):269        self.widget.dispose()270        self.widget = None271272    def test_default_size(self):273        self.assertEqual(self.widget.size(), (50,50),274                         'incorrect default size')275276    def test_resize(self):277        self.widget.resize(100,150)278        self.assertEqual(self.widget.size(), (100,150),279                         'wrong size after resize')280```281282Здесь мы не предоставили метод `runTest()`, а вместо этого предоставили два различных тестовых метода. Теперь каждый экземпляр класса будет запускать один из методов `test_*()`, причём `self.widget` создаётся и уничтожается отдельно для каждого экземпляра. При создании экземпляра необходимо указать, какой тестовый метод он будет выполнять. Это делается путём передачи имени метода в конструктор:283284```python285defaultSizeTestCase = WidgetTestCase('test_default_size')286resizeTestCase = WidgetTestCase('test_resize')287```288289Экземпляры тестовых примеров группируются вместе в соответствии с тестируемыми возможностями. `unittest` предоставляет для этого механизм: *тестовый набор*, представленный классом `unittest`::[`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite):290291```python292widgetTestSuite = unittest.TestSuite()293widgetTestSuite.addTest(WidgetTestCase('test_default_size'))294widgetTestSuite.addTest(WidgetTestCase('test_resize'))295```296297Для удобства запуска тестов, как мы увидим далее, рекомендуется предоставлять в каждом тестовом модуле вызываемый объект, возвращающий предварительно собранный набор тестов:298299```python300def suite():301    suite = unittest.TestSuite()302    suite.addTest(WidgetTestCase('test_default_size'))303    suite.addTest(WidgetTestCase('test_resize'))304    return suite305```306307или даже:308309```python310def suite():311    tests = ['test_default_size', 'test_resize']312313    return unittest.TestSuite(map(WidgetTestCase, tests))314```315316Поскольку создание подкласса [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) с множеством однотипно названных тестовых функций является распространенным шаблоном, `unittest` предоставляет класс [`TestLoader`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader), который можно использовать для автоматизации процесса создания тестового набора и заполнения его отдельными тестами. Например,317318```python319suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)320```321322создаст набор тестов, который выполнит `WidgetTestCase.test_default_size()` и `WidgetTestCase.test_resize`. [`TestLoader`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader) использует префикс имени метода `'test'` для автоматического определения тестовых методов.323324Обратите внимание, что порядок выполнения различных тестовых случаев определяется сортировкой имён тестовых функций в соответствии со встроенным порядком строк.325326Часто желательно группировать наборы тестов вместе, чтобы запускать тесты для всей системы за один раз. Это легко, поскольку экземпляры [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) можно добавлять в [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) так же, как экземпляры [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) можно добавлять в [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite):327328```python329suite1 = module1.TheTestSuite()330suite2 = module2.TheTestSuite()331alltests = unittest.TestSuite([suite1, suite2])332```333334Определения тестовых сценариев и тестовых наборов можно размещать в тех же модулях, что и тестируемый код (например, `widget.py`), но есть несколько преимуществ в размещении тестового кода в отдельном модуле, например `test_widget.py`:335336- Тестовый модуль можно запускать автономно из командной строки.337- Тестовый код проще отделить от поставляемого кода.338- Меньше соблазна изменять тестовый код, чтобы подогнать его под тестируемый код, без веской причины.339- Тестовый код должен изменяться гораздо реже, чем тестируемый код.340- Тестируемый код проще поддаётся рефакторингу.341- Тесты для модулей, написанных на C, всё равно должны быть в отдельных модулях – так почему бы не придерживаться этого подхода?342- Если стратегия тестирования меняется, нет необходимости изменять исходный код.343344## 25.3.4. Повторное использование старого тестового кода345346Некоторые пользователи обнаружат, что у них есть существующий тестовый код, который они хотели бы запустить из `unittest`, без преобразования каждой старой тестовой функции в подкласс [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase).347348По этой причине `unittest` предоставляет класс [`FunctionTestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.FunctionTestCase). Этот подкласс [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) можно использовать для обертывания существующей тестовой функции. Также можно предоставить функции настройки и завершения.349350Рассмотрим следующую тестовую функцию:351352```python353def testSomething():354    something = makeSomething()355    assert something.name is not None356    # ...357```358359можно создать эквивалентный экземпляр тестового случая следующим образом:360361```python362testcase = unittest.FunctionTestCase(testSomething)363```364365Если есть дополнительные методы настройки и очистки, которые должны вызываться в рамках работы тестового случая, их также можно предоставить следующим образом:366367```python368testcase = unittest.FunctionTestCase(testSomething,369                                     setUp=makeSomethingDB,370                                     tearDown=deleteSomethingDB)371```372373Чтобы облегчить миграцию существующих тестовых наборов, `unittest` поддерживает тесты, вызывающие [`AssertionError`](https://python-all.ru/3.1/library/exceptions.html#AssertionError) для указания неудачи теста. Однако рекомендуется вместо этого использовать явные методы `TestCase.fail*()` и `TestCase.assert*()`, так как будущие версии `unittest` могут обрабатывать [`AssertionError`](https://python-all.ru/3.1/library/exceptions.html#AssertionError) иначе.374375> **Примечание**376>377> Хотя [`FunctionTestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.FunctionTestCase) можно использовать для быстрого преобразования существующей тестовой базы в систему на основе `unittest`, этот подход не рекомендуется. Потратив время на создание правильных подклассов [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase), можно значительно упростить будущие рефакторинги тестов.378379В некоторых случаях существующие тесты могут быть написаны с использованием модуля [`doctest`](https://python-all.ru/3.1/library/doctest.html#module-doctest). Если это так, [`doctest`](https://python-all.ru/3.1/library/doctest.html#module-doctest) предоставляет класс `DocTestSuite`, который может автоматически создавать экземпляры [`unittest.TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) из существующих тестов на основе [`doctest`](https://python-all.ru/3.1/library/doctest.html#module-doctest).380381## 25.3.5. Пропуск тестов и ожидаемые неудачи382383Новое в версии 3.1.384385Unittest поддерживает пропуск отдельных тестовых методов и даже целых классов тестов. Кроме того, он поддерживает пометку теста как «ожидаемого сбоя» – теста, который сломан и будет провален, но не должен учитываться как сбой в [`TestResult`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult).386387Пропуск теста – это просто использование [`skip()`](https://python-all.ru/3.1/library/unittest.html#unittest.skip) [*декоратора*](https://python-all.ru/3.1/glossary.html#term-decorator) или одного из его условных вариантов.388389Базовый пропуск выглядит так:390391```python392class MyTestCase(unittest.TestCase):393394    @unittest.skip("demonstrating skipping")395    def test_nothing(self):396        self.fail("shouldn't happen")397398    @unittest.skipIf(mylib.__version__ < (1, 3),399                     "not supported in this library version")400    def test_format(self):401        # Тесты, которые работают только для определённой версии библиотеки.402        pass403404    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")405    def test_windows_support(self):406        # код тестирования для Windows407        pass408```409410Это вывод приведённого выше примера в подробном режиме:411412```python413test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'414test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'415test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'416417----------------------------------------------------------------------418Ran 3 tests in 0.005s419420OK (skipped=3)421```422423Классы можно пропускать так же, как методы:424425```python426@skip("showing class skipping")427class MySkippedTestCase(unittest.TestCase):428    def test_not_run(self):429        pass430```431432[`TestCase.setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp) также может пропустить тест. Это полезно, когда ресурс, который необходимо настроить, недоступен.433434Ожидаемые сбои используют декоратор [`expectedFailure()`](https://python-all.ru/3.1/library/unittest.html#unittest.expectedFailure).435436```python437class ExpectedFailureTestCase(unittest.TestCase):438    @unittest.expectedFailure439    def test_fail(self):440        self.assertEqual(1, 0, "broken")441```442443Легко создать собственные декораторы пропуска, написав декоратор, который вызывает [`skip()`](https://python-all.ru/3.1/library/unittest.html#unittest.skip) для теста, когда его нужно пропустить. Этот декоратор пропускает тест, если переданный объект не имеет определённого атрибута:444445```python446def skipUnlessHasattr(obj, attr):447    if hasattr(obj, attr):448        return lambda func: func449    return unittest.skip("{0!r} doesn't have {1!r}".format(obj, attr))450```451452Следующие декораторы реализуют пропуск тестов и ожидаемые сбои:453454#### `unittest.skip(reason)`455456Безусловно пропускает декорированный тест. Параметр457458*reason*459460должен описывать причину пропуска теста.461462#### `unittest.skipIf(condition, reason)`463464Пропустить декорированный тест, если465466*condition*467468истинно.469470#### `unittest.skipUnless(condition, reason)`471472Пропустить декорированный тест, если473474*condition*475476не истинно.477478#### `unittest.expectedFailure()`479480Помечает тест как ожидаемый сбой. Если тест завершается ошибкой при запуске, он не учитывается как сбой.481482## 25.3.6. Классы и функции483484В этом разделе подробно описывается API `unittest`.485486### 25.3.6.1. Тестовые примеры487488#### `class unittest.TestCase(methodName='runTest')`489490Экземпляры класса [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) представляют наименьшие тестируемые единицы во вселенной `unittest`. Этот класс предназначен для использования в качестве базового класса, при этом конкретные тесты реализуются конкретными подклассами. Этот класс реализует интерфейс, необходимый исполнителю тестов для управления тестом, а также методы, которые тестовый код может использовать для проверки и сообщения о различных типах неудач.491492Каждый экземпляр [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) запускает один тестовый метод: метод с именем *methodName*. Как упоминалось ранее, был пример, выглядевший следующим образом:493494```python495def suite():496    suite = unittest.TestSuite()497    suite.addTest(WidgetTestCase('test_default_size'))498    suite.addTest(WidgetTestCase('test_resize'))499    return suite500```501502Здесь создаются два экземпляра `WidgetTestCase`, каждый из которых выполняет один тест.503504*methodName* по умолчанию равен `runTest()`.505506Экземпляры [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) предоставляют три группы методов: одна группа используется для запуска теста, другая – реализацией теста для проверки условий и сообщения об ошибках, а также некоторые запрашивающие методы, позволяющие получать информацию о самом тесте.507508Методы первой группы (выполнение теста):509510#### `setUp()`511512Метод, вызываемый для подготовки тестового окружения (fixture). Он вызывается непосредственно перед вызовом тестового метода; любое исключение, возбуждённое этим методом, будет считаться ошибкой, а не неудачей теста. Реализация по умолчанию ничего не делает.513514#### `tearDown()`515516Метод, вызываемый сразу после вызова тестового метода и записи результата. Он вызывается, даже если тестовый метод возбудил исключение, поэтому реализация в подклассах должна быть особенно внимательна при проверке внутреннего состояния. Любое исключение, возбуждённое этим методом, будет считаться ошибкой, а не неудачей теста. Этот метод вызывается только в случае успешного выполнения517518[`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp)519520, независимо от результата тестового метода. Реализация по умолчанию ничего не делает.521522#### `run(result=None)`523524Запускает тест, собирая результат в объект результата теста, переданный как *result*. Если *result* опущен или равен `None`, создаётся временный объект результата (вызовом метода [`defaultTestResult()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.defaultTestResult)) и используется. Объект результата не возвращается вызывающему коду [`run()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.run).525526Тот же эффект можно получить, просто вызвав экземпляр [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase).527528#### `skipTest(reason)`529530Вызов этого метода во время выполнения тестового метода или [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp) пропускает текущий тест. См. [*Пропуск тестов и ожидаемые сбои*](https://python-all.ru/3.1/library/unittest.html#unittest-skipping) для получения дополнительной информации.531532Новое в версии 3.1.533534#### `debug()`535536Запускает тест без сбора результата. Это позволяет исключениям, возникшим в тесте, распространяться до вызывающего кода, и может использоваться для поддержки запуска тестов под отладчиком.537538Класс [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) предоставляет ряд методов для проверки и сообщения об ошибках, таких как:539540| Метод | Проверяет, что | Новое в |541| --- | --- | --- |542| [`assertEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual) | `a == b` |  |543| [`assertNotEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertNotEqual) | `a != b` |  |544| [`assertTrue(x)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertTrue) | `bool(x) is True` |  |545| [`assertFalse(x)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertFalse) | `bool(x) is False` |  |546| [`assertIs(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertIs) | `a is b` | 3.1 |547| [`assertIsNot(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertIsNot) | `a is not b` | 3.1 |548| [`assertIsNone(x)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertIsNone) | `x is None` | 3.1 |549| [`assertIsNotNone(x)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertIsNotNone) | `x is not None` | 3.1 |550| [`assertIn(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertIn) | `a in b` | 3.1 |551| [`assertNotIn(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertNotIn) | `a not in b` | 3.1 |552553Все методы assert (за исключением [`assertRaises()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRaises), [`assertRaisesRegexp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRaisesRegexp), `assertWarns()`, `assertWarnsRegexp()`) принимают аргумент *msg*, который, если указан, используется как сообщение об ошибке при неудаче (см. также [`longMessage`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.longMessage)).554555#### `assertEqual(first, second, msg=None)`556557Проверяет, что *first* и *second* равны. Если значения не равны, тест завершится неудачей.558559Кроме того, если *first* и *second* имеют один и тот же тип и являются одним из list, tuple, dict, set, frozenset или str или любым типом, который подкласс регистрирует с помощью [`addTypeEqualityFunc()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.addTypeEqualityFunc), то типовая функция проверки равенства будет вызвана для формирования более полезного сообщения об ошибке по умолчанию (см. также [*список типовых методов*](https://python-all.ru/3.1/library/unittest.html#type-specific-methods)).560561Изменено в версии 3.1: Добавлен автоматический вызов типовой функции проверки равенства.562563#### `assertNotEqual(first, second, msg=None)`564565Проверяет, что566567*first*568569и570571*second*572573не равны. Если значения равны, тест завершится неудачей.574575#### `assertTrue(expr, msg=None)`576577#### `assertFalse(expr, msg=None)`578579Проверяет, что *expr* истинно (или ложно).580581Обратите внимание, что это эквивалентно `bool(expr) is True`, а не `expr is True` (для последнего используйте `assertIs(expr, True)`). Этого метода также следует избегать, когда доступны более специфичные методы (например, `assertEqual(a, b)` вместо `assertTrue(a == b)`), поскольку они предоставляют лучшее сообщение об ошибке в случае неудачи.582583#### `assertIs(first, second, msg=None)`584585#### `assertIsNot(first, second, msg=None)`586587Проверяет, что *first* и *second* являются (или не являются) одним и тем же объектом.588589Новое в версии 3.1.590591#### `assertIsNone(expr, msg=None)`592593#### `assertIsNotNone(expr, msg=None)`594595Проверяет, что *expr* равен (или не равен) None.596597Новое в версии 3.1.598599#### `assertIn(first, second, msg=None)`600601#### `assertNotIn(first, second, msg=None)`602603Проверяет, находится ли *first* в *second* (или не находится).604605Новое в версии 3.1.606607Также можно проверить, что исключения и предупреждения возбуждаются с помощью следующих методов:608609| Метод | Проверяет, что | Новое в |610| --- | --- | --- |611| [`assertRaises(exc, fun, *args, **kwds)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRaises) | `fun(*args, **kwds)` возбуждает *exc* |  |612| [`assertRaisesRegexp(exc, re, fun, *args, **kwds)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRaisesRegexp) | `fun(*args, **kwds)` вызывает *exc* и сообщение соответствует *re* | 3.1 |613614#### `assertRaises(exception, callable, *args, **kwds)`615616#### `assertRaises(exception)`617618Проверяет, что исключение возбуждается, когда *callable* вызывается с любыми позиционными или ключевыми аргументами, которые также передаются в [`assertRaises()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRaises). Тест проходит, если возбуждается *исключение*, является ошибкой, если возбуждается другое исключение, или завершается неудачей, если исключение не возбуждено. Чтобы перехватить любую из группы исключений, можно передать кортеж, содержащий классы исключений, как *исключение*.619620Если указан только аргумент *исключение*, возвращается контекстный менеджер, так что тестируемый код можно писать встроенно, а не в виде функции:621622```python623with self.assertRaises(SomeException):624    do_something()625```626627Изменено в версии 3.1: Добавлена возможность использовать [`assertRaises()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRaises) в качестве менеджера контекста.628629#### `assertRaisesRegexp(exception, regexp, callable, *args, **kwds)`630631#### `assertRaisesRegexp(exception, regexp)`632633Подобно [`assertRaises()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRaises), но также проверяет, что *regexp* соответствует строковому представлению возбуждённого исключения. *regexp* может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящей для использования в [`re.search()`](https://python-all.ru/3.1/library/re.html#re.search). Примеры:634635```python636self.assertRaisesRegexp(ValueError, 'invalid literal for.*XYZ$',637                        int, 'XYZ')638```639640или:641642```python643with self.assertRaisesRegexp(ValueError, 'literal'):644   int('XYZ')645```646647Новое в версии 3.1.648649Существуют также другие методы для выполнения более специфических проверок, например:650651| Метод | Проверяет, что | Новое в |652| --- | --- | --- |653| [`assertAlmostEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertAlmostEqual) | `round(a-b, 7) == 0` |  |654| [`assertNotAlmostEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertNotAlmostEqual) | `round(a-b, 7) != 0` |  |655| [`assertGreater(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertGreater) | `a > b` | 3.1 |656| [`assertGreaterEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertGreaterEqual) | `a >= b` | 3.1 |657| [`assertLess(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertLess) | `a < b` | 3.1 |658| [`assertLessEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertLessEqual) | `a <= b` | 3.1 |659| [`assertRegexpMatches(s, re)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRegexpMatches) | `regex.search(s)` | 3.1 |660| [`assertDictContainsSubset(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertDictContainsSubset) | все пары ключ/значение в *a* присутствуют в *b* | 3.1 |661662#### `assertAlmostEqual(first, second, places=7, msg=None, delta=None)`663664#### `assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)`665666Проверяет, что *first* и *second* приблизительно (или не приблизительно) равны, вычисляя разность, округляя до заданного числа десятичных *знаков* (по умолчанию 7) и сравнивая с нулём. Обратите внимание, что эти методы округляют значения до заданного числа *десятичных знаков* (т.е. как функция [`round()`](https://python-all.ru/3.1/library/functions.html#round)), а не до *значащих цифр*.667668Если указан *delta* вместо *places*, то разница между *first* и *second* должна быть меньше (или больше) *delta*.669670Указание одновременно *delta* и *places* вызывает исключение `TypeError`.671672#### `assertGreater(first, second, msg=None)`673674#### `assertGreaterEqual(first, second, msg=None)`675676#### `assertLess(first, second, msg=None)`677678#### `assertLessEqual(first, second, msg=None)`679680Проверяет, что *first* соответственно \>, \>=, \< или \<= по отношению к *second* в зависимости от имени метода. Если это не так, тест завершается ошибкой:681682```python683>>> self.assertGreaterEqual(3, 4)684AssertionError: "3" unexpectedly not greater than or equal to "4"685```686687Новое в версии 3.1.688689#### `assertRegexpMatches(text, regexp, msg=None)`690691Проверяет, что поиск по *regexp* соответствует *text*. В случае неудачи сообщение об ошибке будет содержать шаблон и *text* (или шаблон и часть *text*, которая неожиданно совпала). *regexp* может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, пригодное для использования в [`re.search()`](https://python-all.ru/3.1/library/re.html#re.search).692693Новое в версии 3.1: [`assertRegexpMatches()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertRegexpMatches)694695#### `assertDictContainsSubset(expected, actual, msg=None)`696697Проверяет, являются ли пары ключ/значение в словаре *actual* надмножеством пар в *expected*. Если нет, создаётся сообщение об ошибке со списком отсутствующих ключей и несовпадающих значений.698699Новое в версии 3.1.700701Устарело с версии 3.2.702703#### `assertSameElements(actual, expected, msg=None)`704705Проверяет, что последовательность *expected* содержит те же элементы, что и *actual*, независимо от их порядка. Если это не так, создаётся сообщение об ошибке со списком различий между последовательностями.706707Дублирующиеся элементы игнорируются при сравнении *actual* и *expected*. Это эквивалентно `assertEqual(set(expected), set(actual))`, но работает также с последовательностями нехэшируемых объектов. Поскольку дубликаты игнорируются, этот метод устарел в пользу `assertItemsEqual()`.708709Новое в версии 3.1.710711Устарело с версии 3.2.712713Метод [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual) направляет проверку равенства для объектов одного типа к различным методам, специфичным для типа. Эти методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощью [`addTypeEqualityFunc()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.addTypeEqualityFunc):714715#### `addTypeEqualityFunc(typeobj, function)`716717Регистрирует метод, специфичный для типа, который вызывается [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual) для проверки, равны ли два объекта одного и того же *typeobj* (не подклассы). *function* должен принимать два позиционных аргумента и третий именованный аргумент msg=None, как и [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual). Он должен вызывать исключение [`self.failureException(msg)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.failureException) при обнаружении неравенства между первыми двумя параметрами – возможно, предоставляя полезную информацию и подробно объясняя неравенства в сообщении об ошибке.718719Новое в версии 3.1.720721Список методов, специфичных для типа, автоматически используемых [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual), приведен в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать эти методы напрямую.722723| Метод | Используется для сравнения | Новое в |724| --- | --- | --- |725| [`assertMultiLineEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertMultiLineEqual) | строки | 3.1 |726| [`assertSequenceEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertSequenceEqual) | последовательности | 3.1 |727| [`assertListEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertListEqual) | списки | 3.1 |728| [`assertTupleEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertTupleEqual) | кортежи | 3.1 |729| [`assertSetEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertSetEqual) | множества или неизменяемые множества | 3.1 |730| [`assertDictEqual(a, b)`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertDictEqual) | словари | 3.1 |731732#### `assertMultiLineEqual(first, second, msg=None)`733734Проверяет, что многострочная строка *first* равна строке *second*. При неравенстве в сообщение об ошибке будет включена разница между двумя строками с выделением отличий. Этот метод используется по умолчанию при сравнении строк с [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual).735736Новое в версии 3.1.737738#### `assertSequenceEqual(seq1, seq2, msg=None, seq_type=None)`739740Проверяет, что две последовательности равны. Если указан *seq\_type*, то и *seq1*, и *seq2* должны быть экземплярами *seq\_type*, иначе возникнет ошибка. Если последовательности различаются, формируется сообщение об ошибке, показывающее разницу между ними.741742Этот метод не вызывается напрямую [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual), но используется для реализации [`assertListEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertListEqual) и [`assertTupleEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertTupleEqual).743744Новое в версии 3.1.745746#### `assertListEqual(list1, list2, msg=None)`747748#### `assertTupleEqual(tuple1, tuple2, msg=None)`749750Проверяет, что два списка или кортежа равны. Если нет, формируется сообщение об ошибке, показывающее только различия между ними. Ошибка также возникает, если любой из параметров имеет неверный тип. Эти методы используются по умолчанию при сравнении списков или кортежей с [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual).751752Новое в версии 3.1.753754#### `assertSetEqual(set1, set2, msg=None)`755756Проверяет, что два множества равны. Если нет, формируется сообщение об ошибке, в котором перечислены различия между множествами. Этот метод используется по умолчанию при сравнении множеств или frozensets с [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual).757758Завершается ошибкой, если *set1* или *set2* не имеют метода [`set.difference()`](https://python-all.ru/3.1/library/stdtypes.html#set.difference).759760Новое в версии 3.1.761762#### `assertDictEqual(expected, actual, msg=None)`763764Проверяет, что два словаря равны. Если нет, формируется сообщение об ошибке, показывающее различия в словарях. Этот метод будет использоваться по умолчанию для сравнения словарей в вызовах [`assertEqual()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.assertEqual).765766Новое в версии 3.1.767768Наконец, [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) предоставляет следующие методы и атрибуты:769770#### `fail(msg=None)`771772Безусловно сообщает о провале теста, с773774*msg*775776или777778`None`779780в качестве сообщения об ошибке.781782#### `failureException`783784Этот атрибут класса задаёт исключение, возбуждаемое тестовым методом. Если тестовой платформе нужно использовать специализированное исключение, возможно, для передачи дополнительной информации, она должна создать подкласс этого исключения, чтобы корректно работать с платформой. Начальное значение этого атрибута –785786[`AssertionError`](https://python-all.ru/3.1/library/exceptions.html#AssertionError)787788.789790#### `longMessage`791792Если установлено в `True`, то любое явное сообщение об ошибке, переданное в [*assert-методы*](https://python-all.ru/3.1/library/unittest.html#assert-methods), будет добавлено в конец стандартного сообщения об ошибке. Стандартные сообщения содержат полезную информацию о вовлечённых объектах, например, сообщение от assertEqual показывает repr двух неравных объектов. Установка этого атрибута в `True` позволяет иметь пользовательское сообщение об ошибке в дополнение к стандартному.793794По умолчанию этот атрибут равен `False`, то есть пользовательское сообщение, переданное методу проверки, подавляет стандартное сообщение.795796Настройку класса можно переопределить в отдельных тестах, назначив атрибут экземпляра в `True` или `False` перед вызовом методов assert.797798Новое в версии 3.1.799800Тестовые фреймворки могут использовать следующие методы для сбора информации о тесте:801802#### `countTestCases()`803804Возвращает количество тестов, представленных этим тестовым объектом. Для экземпляров805806[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)807808это значение всегда равно809810`1`811812.813814#### `defaultTestResult()`815816Возвращает экземпляр класса результата теста, который следует использовать для этого класса тестового случая (если другой экземпляр результата не предоставлен методу [`run()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.run)).817818Для экземпляров [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) это всегда будет экземпляр [`TestResult`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult); подклассы [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) должны переопределять это при необходимости.819820#### `id()`821822Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя тестового метода, включая имя модуля и класса.823824#### `shortDescription()`825826Возвращает описание теста или `None`, если описание не было указано. Реализация по умолчанию этого метода возвращает первую строку докстринга тестового метода, если он есть, вместе с именем метода.827828Изменено в версии 3.1: В предыдущих версиях это возвращало только первую строку докстринга тестового метода, если он был, или [`None`](https://python-all.ru/3.1/library/constants.html#None). Это приводило к нежелательному поведению – имя теста не печаталось, когда кто-то был настолько предусмотрителен, что написал докстринг.829830#### `addCleanup(function, *args, **kwargs)`831832Добавляет функцию, которая будет вызвана после [`tearDown()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.tearDown) для очистки ресурсов, используемых во время теста. Функции будут вызываться в порядке, обратном порядку их добавления (LIFO). Они вызываются с теми аргументами и именованными аргументами, которые были переданы в [`addCleanup()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.addCleanup) при их добавлении.833834Если [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp) завершается неудачей, так что [`tearDown()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.tearDown) не вызывается, то все добавленные функции очистки всё равно будут вызваны.835836Новое в версии 3.1.837838#### `doCleanups()`839840Этот метод вызывается безусловно после [`tearDown()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.tearDown), или после [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp), если [`setUp()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.setUp) возбуждает исключение.841842Он отвечает за вызов всех функций очистки, добавленных с помощью [`addCleanup()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.addCleanup). Если нужно, чтобы функции очистки вызывались *до* [`tearDown()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.tearDown), то можно вызвать [`doCleanups()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.doCleanups) самостоятельно.843844[`doCleanups()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.doCleanups) извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любое время.845846Новое в версии 3.1.847848#### `class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)`849850Этот класс реализует часть интерфейса851852[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)853854, которая позволяет тестовому раннеру запускать тест, но не предоставляет методы, которые тестовый код может использовать для проверки и сообщения об ошибках. Он используется для создания тестовых случаев с использованием устаревшего тестового кода, позволяя интегрировать его в тестовую среду на основе855856`unittest`857858.859860#### 25.3.6.1.1. Устаревшие псевдонимы861862По историческим причинам некоторые методы [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) имели один или несколько псевдонимов, которые теперь устарели. В следующей таблице перечислены правильные имена вместе с их устаревшими псевдонимами:863864> | Имя метода | Устаревшие псевдонимы |865> | --- | --- |866> | `assertEqual()` | failUnlessEqual, assertEquals |867> | `assertNotEqual()` | failIfEqual |868> | `assertTrue()` | failUnless, assert\_ |869> | `assertFalse()` | failIf |870> | `assertRaises()` | failUnlessRaises |871> | `assertAlmostEqual()` | failUnlessAlmostEqual |872> | `assertNotAlmostEqual()` | failIfAlmostEqual |873>874> Устарело с версии 3.1: псевдонимы, перечисленные во втором столбце875876### 25.3.6.2. Группировка тестов877878#### `class unittest.TestSuite(tests=())`879880Этот класс представляет собой агрегацию отдельных тестовых случаев и тестовых наборов. Он предоставляет интерфейс, необходимый тестовому раннеру, чтобы его можно было запускать как любой другой тестовый случай. Запуск экземпляра [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) равносилен итерации по набору с запуском каждого теста по отдельности.881882Если задан *tests*, он должен быть итерабельным объектом, содержащим отдельные тестовые примеры или другие тестовые наборы, которые будут использоваться для первоначального построения набора. Дополнительные методы предоставляются для добавления тестовых примеров и наборов в коллекцию позже.883884Объекты [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) во многом аналогичны объектам [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase), за исключением того, что они не реализуют тест напрямую. Вместо этого они служат для объединения тестов в группы, которые должны выполняться совместно. Есть несколько дополнительных методов для добавления тестов в экземпляры [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite):885886#### `addTest(test)`887888Добавляет объект889890[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)891892или893894[`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite)895896в набор.897898#### `addTests(tests)`899900Добавляет все тесты из итерируемого объекта, содержащего экземпляры [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) и [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite), в данный тестовый набор.901902Это эквивалентно перебору *tests* с вызовом [`addTest()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite.addTest) для каждого элемента.903904[`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) имеет общие следующие методы с [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase):905906#### `run(result)`907908Запускает тесты, связанные с этим набором, собирая результат в объект результата теста, переданный как909910*result*911912. Обратите внимание, что, в отличие от913914[`TestCase.run()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase.run)915916,917918[`TestSuite.run()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite.run)919920требует обязательной передачи объекта результата.921922#### `debug()`923924Запускает тесты, связанные с этим набором, без сбора результата. Это позволяет исключениям, возбуждённым тестом, распространяться до вызывающего кода и может использоваться для поддержки запуска тестов под отладчиком.925926#### `countTestCases()`927928Возвращает количество тестов, представленных этим тестовым объектом, включая все отдельные тесты и поднаборы.929930#### `__iter__()`931932Тесты, сгруппированные в933934[`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite)935936, всегда извлекаются через итерацию. Подклассы могут предоставлять тесты лениво, переопределяя937938[`__iter__()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite.__iter__)939940. Обратите внимание, что этот метод может вызываться несколько раз для одного набора (например, при подсчёте тестов или сравнении на равенство) поэтому на всех повторных итерациях должны возвращаться одни и те же тесты.941942В типичном использовании объекта [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) метод [`run()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite.run) вызывается `TestRunner`, а не тестовым стендом конечного пользователя.943944### 25.3.6.3. Загрузка и запуск тестов945946#### `class unittest.TestLoader`947948Класс [`TestLoader`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader) используется для создания наборов тестов из классов и модулей. Обычно нет необходимости создавать экземпляр этого класса; модуль `unittest` предоставляет экземпляр, который можно использовать как `unittest.defaultTestLoader`. Однако использование подкласса или экземпляра позволяет настраивать некоторые параметры конфигурации.949950Объекты [`TestLoader`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader) имеют следующие методы:951952#### `loadTestsFromTestCase(testCaseClass)`953954Возвращает набор всех тестовых случаев, содержащихся в классе955956`testCaseClass`957958, производном от959960[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)961962.963964#### `loadTestsFromModule(module)`965966Возвращает набор всех тестовых случаев, содержащихся в данном модуле. Этот метод ищет в *module* классы, производные от [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase), и создает экземпляр класса для каждого тестового метода, определенного в классе.967968> **Примечание**969>970> Хотя использование иерархии классов, производных от [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase), может быть удобным для совместного использования фикстур и вспомогательных функций, определение тестовых методов в базовых классах, которые не предназначены для прямого инстанцирования, плохо сочетается с этим методом. Однако это может быть полезно, когда фикстуры различаются и определяются в подклассах.971972#### `loadTestsFromName(name, module=None)`973974Возвращает набор всех тестовых случаев по строковому спецификатору.975976Спецификатор *name* – это «точечное имя», которое может разрешаться в модуль, класс тестового случая, тестовый метод внутри класса тестового случая, экземпляр [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) или вызываемый объект, возвращающий экземпляр [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite). Эти проверки применяются в указанном порядке; то есть метод в классе возможного тестового случая будет распознан как «тестовый метод внутри класса тестового случая», а не как «вызываемый объект».977978Например, если у вас есть модуль `SampleTests`, содержащий класс `SampleTestCase`, производный от [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase), с тремя тестовыми методами (`test_one()`, `test_two()` и `test_three()`), то спецификатор `'SampleTests.SampleTestCase'` приведет к тому, что этот метод вернет набор, который запустит все три тестовых метода. Использование спецификатора `'SampleTests.SampleTestCase.test_two'` приведет к возврату тестового набора, который запустит только тестовый метод `test_two()`. Спецификатор может ссылаться на модули и пакеты, которые еще не были импортированы; они будут импортированы как побочный эффект.979980Метод опционально разрешает *name* относительно заданного *module*.981982#### `loadTestsFromNames(names, module=None)`983984Аналогично985986[`loadTestsFromName()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader.loadTestsFromName)987988, но принимает последовательность имён, а не одно имя. Возвращаемое значение – тестовый набор, содержащий все тесты, определённые для каждого имени.989990#### `getTestCaseNames(testCaseClass)`991992Возвращает отсортированную последовательность имён методов, найденных в993994*testCaseClass*995996; и он должен быть997998[подклассом `TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)9991000.10011002Следующие атрибуты [`TestLoader`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader) можно настроить либо через создание подкласса, либо присваиванием экземпляру:10031004#### `testMethodPrefix`10051006Строка, задающая префикс имён методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию – `'test'`.10071008Это влияет на [`getTestCaseNames()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader.getTestCaseNames) и все методы `loadTestsFrom*()`.10091010#### `sortTestMethodsUsing`10111012Функция, используемая для сравнения имён методов при сортировке в10131014[`getTestCaseNames()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader.getTestCaseNames)10151016и во всех методах10171018`loadTestsFrom*()`10191020.10211022#### `suiteClass`10231024Вызываемый объект, который создаёт тестовый набор из списка тестов. Никакие методы результирующего объекта не требуются. Значение по умолчанию – класс [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite).10251026Это влияет на все методы `loadTestsFrom*()`.10271028#### `class unittest.TestResult`10291030Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие завершились неудачей.10311032Объект [`TestResult`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult) хранит результаты набора тестов. Классы [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) и [`TestSuite`](https://python-all.ru/3.1/library/unittest.html#unittest.TestSuite) обеспечивают корректную запись результатов; авторам тестов не нужно заботиться о записи результатов тестов.10331034Фреймворки для тестирования, построенные на основе `unittest`, могут нуждаться в доступе к объекту [`TestResult`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult), который создаётся при запуске набора тестов для отчётности; экземпляр [`TestResult`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult) возвращается методом `TestRunner.run()` для этой цели.10351036Экземпляры [`TestResult`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult) имеют следующие атрибуты, которые будут интересны при просмотре результатов выполнения набора тестов:10371038#### `errors`10391040Список, содержащий кортежи из двух элементов: экземпляры10411042[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)10431044и строки с форматированными трассировками. Каждый кортеж представляет тест, вызвавший неожиданное исключение.10451046#### `failures`10471048Список, содержащий кортежи из двух элементов: экземпляров10491050[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)10511052и строк с отформатированными трассировками. Каждый кортеж представляет тест, в котором сбой был явно зафиксирован с помощью методов10531054`TestCase.fail*()`10551056или10571058`TestCase.assert*()`10591060.10611062#### `skipped`10631064Список, содержащий кортежи из двух элементов: экземпляры [`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase) и строки с причиной пропуска теста.10651066Новое в версии 3.1.10671068#### `expectedFailures`10691070Список, содержащий кортежи из двух элементов: экземпляры10711072[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)10731074и строки с форматированными трассировками. Каждый кортеж представляет ожидаемую ошибку тестового случая.10751076#### `unexpectedSuccesses`10771078Список, содержащий экземпляры10791080[`TestCase`](https://python-all.ru/3.1/library/unittest.html#unittest.TestCase)10811082, которые были отмечены как ожидаемые ошибки, но прошли успешно.10831084#### `shouldStop`10851086Устанавливается в10871088`True`10891090, когда выполнение тестов должно быть остановлено вызовом10911092[`stop()`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult.stop)10931094.10951096#### `testsRun`10971098Общее количество запущенных на данный момент тестов.10991100#### `wasSuccessful()`11011102Возвращает11031104`True`11051106, если все выполненные на данный момент тесты прошли, иначе возвращает11071108`False`11091110.11111112#### `stop()`11131114Этот метод может быть вызван, чтобы сигнализировать, что выполняемый набор тестов должен быть прерван установкой атрибута [`shouldStop`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult.shouldStop) в `True`. Объекты `TestRunner` должны учитывать этот флаг и возвращаться без выполнения дополнительных тестов.11151116Например, эта возможность используется классом [`TextTestRunner`](https://python-all.ru/3.1/library/unittest.html#unittest.TextTestRunner) для остановки тестового фреймворка, когда пользователь подает сигнал прерывания с клавиатуры. Интерактивные инструменты, предоставляющие реализации `TestRunner`, могут использовать это аналогичным образом.11171118Следующие методы класса [`TestResult`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult) используются для поддержки внутренних структур данных и могут быть расширены в подклассах для поддержки дополнительных требований к отчетности. Это особенно полезно при создании инструментов, поддерживающих интерактивную отчетность во время выполнения тестов.11191120#### `startTest(test)`11211122Вызывается перед запуском тестового сценария *test*.11231124Реализация по умолчанию просто увеличивает счётчик [`testsRun`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult.testsRun) экземпляра.11251126#### `stopTest(test)`11271128Вызывается после выполнения тестового сценария *test*, независимо от результата.11291130Реализация по умолчанию ничего не делает.11311132#### `startTestRun(test)`11331134Вызывается один раз перед выполнением любых тестов.11351136Новое в версии 3.1.11371138#### `stopTestRun(test)`11391140Вызывается один раз после выполнения всех тестов.11411142Новое в версии 3.1.11431144#### `addError(test, err)`11451146Вызывается, когда тестовый сценарий *test* вызывает неожиданное исключение. *err* – это кортеж в формате, возвращаемом [`sys.exc_info()`](https://python-all.ru/3.1/library/sys.html#sys.exc_info): `(type, value, traceback)`.11471148Реализация по умолчанию добавляет кортеж `(test, formatted_err)` в атрибут [`errors`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult.errors) экземпляра, где *formatted\_err* – это форматированная трассировка, полученная из *err*.11491150#### `addFailure(test, err)`11511152Вызывается, когда тестовый пример *test* сигнализирует о неудаче. *err* – это кортеж в формате, возвращаемом [`sys.exc_info()`](https://python-all.ru/3.1/library/sys.html#sys.exc_info): `(type, value, traceback)`.11531154Реализация по умолчанию добавляет кортеж `(test, formatted_err)` в атрибут [`failures`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult.failures) экземпляра, где *formatted\_err* – это форматированная трассировка, полученная из *err*.11551156#### `addSuccess(test)`11571158Вызывается, когда тестовый сценарий *test* завершается успешно.11591160Реализация по умолчанию ничего не делает.11611162#### `addSkip(test, reason)`11631164Вызывается, когда тестовый сценарий *test* пропускается. *reason* – причина, которую тест указал для пропуска.11651166Реализация по умолчанию добавляет кортеж `(test, reason)` в атрибут [`skipped`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult.skipped) экземпляра.11671168#### `addExpectedFailure(test, err)`11691170Вызывается, когда тестовый пример *test* завершается неудачей, но был помечен декоратором [`expectedFailure()`](https://python-all.ru/3.1/library/unittest.html#unittest.expectedFailure).11711172Реализация по умолчанию добавляет кортеж `(test, formatted_err)` в атрибут [`expectedFailures`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult.expectedFailures) экземпляра, где *formatted\_err* – это форматированная трассировка, полученная из *err*.11731174#### `addUnexpectedSuccess(test)`11751176Вызывается, когда тестовый пример *test* был помечен декоратором [`expectedFailure()`](https://python-all.ru/3.1/library/unittest.html#unittest.expectedFailure), но завершился успешно.11771178Реализация по умолчанию добавляет тест в атрибут [`unexpectedSuccesses`](https://python-all.ru/3.1/library/unittest.html#unittest.TestResult.unexpectedSuccesses) экземпляра.11791180#### `unittest.defaultTestLoader`11811182Экземпляр класса11831184[`TestLoader`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader)11851186, предназначенный для совместного использования. Если настройка11871188[`TestLoader`](https://python-all.ru/3.1/library/unittest.html#unittest.TestLoader)11891190не требуется, можно использовать этот экземпляр вместо многократного создания новых.11911192#### `class unittest.TextTestRunner(stream=sys.stderr, descriptions=True, verbosity=1)`11931194Базовая реализация исполнителя тестов, которая выводит результаты в стандартный поток ошибок. Она имеет несколько настраиваемых параметров, но в целом очень проста. Графические приложения, запускающие тестовые наборы, должны предоставлять альтернативные реализации.11951196#### `_makeResult()`11971198Этот метод возвращает экземпляр11991200`TestResult`12011202, используемый12031204`run()`12051206. Он не предназначен для прямого вызова, но может быть переопределён в подклассах для предоставления собственного12071208`TestResult`12091210.12111212#### `unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=TextTestRunner, testLoader=unittest.defaultTestLoader, exit=True)`12131214Командная программа, которая запускает набор тестов; это в первую очередь для того, чтобы сделать tестовые модули удобно исполняемыми. Простейшее использование этой функции – добавить следующую строку в конец тестового скрипта:12151216```python1217if __name__ == '__main__':1218    unittest.main()1219```12201221Аргумент *testRunner* может быть либо классом средства запуска тестов, либо уже созданным экземпляром такого класса. По умолчанию `main` вызывает [`sys.exit()`](https://python-all.ru/3.1/library/sys.html#sys.exit) с кодом возврата, указывающим на успех или неудачу выполнения тестов.12221223`main` поддерживает использование из интерактивного интерпретатора путём передачи аргумента `exit=False`. При этом результат выводится на стандартный вывод без вызова [`sys.exit()`](https://python-all.ru/3.1/library/sys.html#sys.exit):12241225```python1226>>> from unittest import main1227>>> main(module='test_module', exit=False)1228```12291230Вызов `main` на самом деле возвращает экземпляр класса `TestProgram`. Результат выполнения тестов сохраняется в атрибуте `result`.12311232Изменено в версии 3.1: был добавлен параметр `exit`.1233