unittest.md
1> **Источник:** https://python-all.ru/3.0/library/unittest.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `unittest` – фреймворк модульного тестирования89Среда модульного тестирования Python, иногда называемая «PyUnit», является реализацией JUnit на языке Python, созданной Кентом Беком и Эрихом Гаммой. JUnit, в свою очередь, представляет собой Java-версию среды тестирования Smalltalk Кента Бека. Каждая из них является фактическим стандартом модульного тестирования для своего языка.1011`unittest` поддерживает автоматизацию тестирования, совместное использование кода настройки и завершения для тестов, объединение тестов в коллекции и независимость тестов от фреймворка отчетности. Модуль `unittest` предоставляет классы, которые упрощают поддержку этих качеств для набора тестов.1213Для этого `unittest` поддерживает несколько важных концепций:1415**тестовая фикстура**1617*Тестовая фикстура*1819представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, и любые сопутствующие действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск серверного процесса.2021**тестовый случай**2223*Тестовый пример*2425– это наименьшая единица тестирования. Он проверяет определенную реакцию на конкретный набор входных данных.2627`unittest`2829предоставляет базовый класс3031[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)3233, который можно использовать для создания новых тестовых примеров.3435**набор тестов**3637*Набор тестов*3839– это совокупность тестовых случаев, наборов тестов или и того, и другого. Он используется для объединения тестов, которые должны выполняться вместе.4041**исполнитель тестов**4243*Исполнитель тестов*4445– это компонент, который управляет выполнением тестов и предоставляет результат пользователю. Исполнитель может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение, указывающее на результаты выполнения тестов.4647Концепции тестового примера и тестового оснащения поддерживаются через классы [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) и [`FunctionTestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.FunctionTestCase); первый следует использовать при создании новых тестов, а последний – при интеграции существующего тестового кода с фреймворком на основе `unittest`. При создании тестовых оснащений с помощью [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) можно переопределить методы `setUp()` и `tearDown()` для инициализации и очистки оснащения. С помощью [`FunctionTestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.FunctionTestCase) в конструктор можно передавать существующие функции для тех же целей. При запуске теста сначала выполняется инициализация оснащения; если она успешна, метод очистки запускается после выполнения теста независимо от его результата. Каждый экземпляр [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) будет использоваться только для одного метода теста, поэтому для каждого теста создаётся новое оснащение.4849Тестовые наборы реализуются классом [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite). Этот класс позволяет объединять отдельные тесты и тестовые наборы; при выполнении набора запускаются все тесты, добавленные непосредственно в набор и в «дочерние» тестовые наборы.5051Тестовый раннер – это объект, предоставляющий единственный метод `run()`, который принимает объект [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) в качестве параметра и возвращает объект с результатами. Класс [`TestResult`](https://python-all.ru/3.0/library/unittest.html#unittest.TestResult) предоставляется для использования в качестве объекта результата. `unittest` предоставляет [`TextTestRunner`](https://python-all.ru/3.0/library/unittest.html#unittest.TextTestRunner) в качестве примера тестового раннера, который по умолчанию выводит результаты тестов в поток стандартных ошибок. Альтернативные раннеры могут быть реализованы для других сред (например, графических) без необходимости наследования от конкретного класса.5253> **См. также**54>55> **Модуль [`doctest`](https://python-all.ru/3.0/library/doctest.html#module-doctest)**56>57> Ещё один модуль поддержки тестирования с совершенно другим подходом.58>59> **[Простое тестирование в Smalltalk: с шаблонами](https://python-all.ru/3.0/library/unittest.html)**60>61> Оригинальная статья Кента Бека о тестовых фреймворках, использующих шаблон, общий для62>63> `unittest`64>65> .6667## Простой пример6869Модуль `unittest` предоставляет богатый набор инструментов для создания и запуска тестов. В этом разделе показано, что небольшого подмножества инструментов достаточно для удовлетворения потребностей большинства пользователей.7071Вот короткий скрипт для тестирования трёх функций из модуля [`random`](https://python-all.ru/3.0/library/random.html#module-random):7273```python74import random75import unittest7677class TestSequenceFunctions(unittest.TestCase):7879 def setUp(self):80 self.seq = range(10)8182 def testshuffle(self):83 # make sure the shuffled sequence does not lose any elements84 random.shuffle(self.seq)85 self.seq.sort()86 self.assertEqual(self.seq, range(10))8788 def testchoice(self):89 element = random.choice(self.seq)90 self.assert_(element in self.seq)9192 def testsample(self):93 self.assertRaises(ValueError, random.sample, self.seq, 20)94 for element in random.sample(self.seq, 5):95 self.assert_(element in self.seq)9697if __name__ == '__main__':98 unittest.main()99```100101Тестовый пример создаётся путём создания подкласса [`unittest.TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase). Три отдельных теста определяются методами, имена которых начинаются с букв `test`. Это соглашение об именах сообщает тестовому раннеру, какие методы представляют тесты.102103Суть каждого теста – вызов `assertEqual()` для проверки ожидаемого результата; `assert_()` для проверки условия; или `assertRaises()` для проверки возбуждения ожидаемого исключения. Эти методы используются вместо инструкции [`assert`](https://python-all.ru/3.0/reference/simple_stmts.html#assert), чтобы тестовый раннер мог накопить все результаты тестов и сформировать отчёт.104105Если определён метод `setUp()`, тестовый раннер выполнит его перед каждым тестом. Аналогично, если определён метод `tearDown()`, раннер вызовет его после каждого теста. В примере `setUp()` использовался для создания новой последовательности для каждого теста.106107Последний блок демонстрирует простой способ запуска тестов. [`unittest.main()`](https://python-all.ru/3.0/library/unittest.html#unittest.main) предоставляет интерфейс командной строки для тестового скрипта. При запуске из командной строки указанный скрипт выдаёт вывод, который выглядит так:108109```python110...111----------------------------------------------------------------------112Ran 3 tests in 0.000s113114OK115```116117Вместо [`unittest.main()`](https://python-all.ru/3.0/library/unittest.html#unittest.main) существуют другие способы запуска тестов с более точным контролем, менее лаконичным выводом и без необходимости запуска из командной строки. Например, последние две строки можно заменить на:118119```python120suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)121unittest.TextTestRunner(verbosity=2).run(suite)122```123124Запуск изменённого скрипта из интерпретатора или другого скрипта приводит к следующему выводу:125126```python127testchoice (__main__.TestSequenceFunctions) ... ok128testsample (__main__.TestSequenceFunctions) ... ok129testshuffle (__main__.TestSequenceFunctions) ... ok130131----------------------------------------------------------------------132Ran 3 tests in 0.110s133134OK135```136137Приведенные выше примеры демонстрируют наиболее часто используемые возможности `unittest`, которых достаточно для многих повседневных задач тестирования. Остальная часть документации исследует полный набор возможностей с нуля.138139## Организация тестового кода140141Основными строительными блоками модульного тестирования являются *тестовые примеры* – отдельные сценарии, которые необходимо настроить и проверить на корректность. В `unittest` тестовые примеры представлены экземплярами класса `unittest`::[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase). Чтобы создать собственные тестовые примеры, нужно написать подклассы [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) или использовать [`FunctionTestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.FunctionTestCase).142143Экземпляр класса, производного от [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase), представляет собой объект, который может полностью выполнить один тестовый метод вместе с необязательным кодом настройки и очистки.144145Тестовый код экземпляра [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) должен быть полностью самодостаточным, чтобы его можно было запускать как изолированно, так и в произвольной комбинации с любым количеством других тестовых сценариев.146147Простейший подкласс [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) просто переопределяет метод `runTest()` для выполнения конкретного тестового кода:148149```python150import unittest151152class DefaultWidgetSizeTestCase(unittest.TestCase):153 def runTest(self):154 widget = Widget('The widget')155 self.assertEqual(widget.size(), (50, 50), 'incorrect default size')156```157158Обратите внимание: для проверки чего-либо используются методы `assert*()` или `fail*()`, предоставляемые базовым классом [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase). Если тест не пройден, возбуждается исключение, и `unittest` помечает тестовый пример как *неудачу*. Любые другие исключения рассматриваются как *ошибки*. Это помогает определить источник проблемы: *неудачи* вызваны неверными результатами – например, 5 вместо ожидаемой 6. *Ошибки* вызваны некорректным кодом – например, [`TypeError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.TypeError) из-за неверного вызова функции.159160Способ запуска тестового примера будет описан позже. Пока обратите внимание, что для создания экземпляра такого тестового примера мы вызываем его конструктор без аргументов:161162```python163testCase = DefaultWidgetSizeTestCase()164```165166Теперь таких тестовых примеров может быть много, и их настройка может повторяться. В приведённом выше случае создание `Widget` в каждом из 100 подклассов тестовых примеров Widget привело бы к некрасивому дублированию.167168К счастью, мы можем вынести такой код настройки, реализовав метод `setUp()`, который тестовый фреймворк будет автоматически вызывать при запуске теста:169170```python171import unittest172173class SimpleWidgetTestCase(unittest.TestCase):174 def setUp(self):175 self.widget = Widget('The widget')176177class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):178 def runTest(self):179 self.failUnless(self.widget.size() == (50,50),180 'incorrect default size')181182class WidgetResizeTestCase(SimpleWidgetTestCase):183 def runTest(self):184 self.widget.resize(100,150)185 self.failUnless(self.widget.size() == (100,150),186 'wrong size after resize')187```188189Если метод `setUp()` возбуждает исключение во время выполнения теста, фреймворк сочтёт, что в тесте произошла ошибка, и метод `runTest()` не будет выполнен.190191Аналогично, можно определить метод `tearDown()`, который выполняет очистку после выполнения метода `runTest()`:192193```python194import unittest195196class SimpleWidgetTestCase(unittest.TestCase):197 def setUp(self):198 self.widget = Widget('The widget')199200 def tearDown(self):201 self.widget.dispose()202 self.widget = None203```204205Если `setUp()` выполнен успешно, метод `tearDown()` будет выполнен независимо от того, успешен ли `runTest()` или нет.206207Такое рабочее окружение для тестового кода называется *фикстурой*.208209Часто много маленьких тестовых примеров используют одну и ту же фикстуру. В этом случае пришлось бы создавать подклассы `SimpleWidgetTestCase` для множества маленьких классов с одним методом, таких как `DefaultWidgetSizeTestCase`. Это отнимает много времени и обескураживает, поэтому, следуя примеру JUnit, `unittest` предоставляет более простой механизм:210211```python212import unittest213214class WidgetTestCase(unittest.TestCase):215 def setUp(self):216 self.widget = Widget('The widget')217218 def tearDown(self):219 self.widget.dispose()220 self.widget = None221222 def testDefaultSize(self):223 self.failUnless(self.widget.size() == (50,50),224 'incorrect default size')225226 def testResize(self):227 self.widget.resize(100,150)228 self.failUnless(self.widget.size() == (100,150),229 'wrong size after resize')230```231232Здесь мы не определили метод `runTest()`, а вместо этого определили два разных тестовых метода. Теперь каждый экземпляр класса будет выполнять один из методов `test*()`, при этом `self.widget` создаётся и уничтожается отдельно для каждого экземпляра. При создании экземпляра мы должны указать, какой тестовый метод он должен выполнять. Это делается передачей имени метода в конструктор:233234```python235defaultSizeTestCase = WidgetTestCase('testDefaultSize')236resizeTestCase = WidgetTestCase('testResize')237```238239Экземпляры тестовых примеров группируются вместе в соответствии с тестируемыми возможностями. `unittest` предоставляет для этого механизм: *тестовый набор*, представленный классом `unittest`::[`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite):240241```python242widgetTestSuite = unittest.TestSuite()243widgetTestSuite.addTest(WidgetTestCase('testDefaultSize'))244widgetTestSuite.addTest(WidgetTestCase('testResize'))245```246247Для удобства запуска тестов, как мы увидим далее, рекомендуется предоставлять в каждом тестовом модуле вызываемый объект, возвращающий предварительно собранный набор тестов:248249```python250def suite():251 suite = unittest.TestSuite()252 suite.addTest(WidgetTestCase('testDefaultSize'))253 suite.addTest(WidgetTestCase('testResize'))254 return suite255```256257или даже:258259```python260def suite():261 tests = ['testDefaultSize', 'testResize']262263 return unittest.TestSuite(map(WidgetTestCase, tests))264```265266Поскольку создание подкласса [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) с множеством однотипно названных тестовых функций является распространенным шаблоном, `unittest` предоставляет класс [`TestLoader`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader), который можно использовать для автоматизации процесса создания тестового набора и заполнения его отдельными тестами. Например,267268```python269suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)270```271272создаст тестовый набор, который выполнит `WidgetTestCase.testDefaultSize()` и `WidgetTestCase.testResize`. [`TestLoader`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader) использует префикс имени метода `'test'` для автоматического определения тестовых методов.273274Обратите внимание, что порядок выполнения различных тестовых случаев определяется сортировкой имён тестовых функций в соответствии со встроенным порядком строк.275276Часто желательно группировать наборы тестов вместе, чтобы запускать тесты для всей системы за один раз. Это легко, поскольку экземпляры [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) можно добавлять в [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) так же, как экземпляры [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) можно добавлять в [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite):277278```python279suite1 = module1.TheTestSuite()280suite2 = module2.TheTestSuite()281alltests = unittest.TestSuite([suite1, suite2])282```283284Определения тестовых сценариев и тестовых наборов можно размещать в тех же модулях, что и тестируемый код (например, `widget.py`), но есть несколько преимуществ в размещении тестового кода в отдельном модуле, например `test_widget.py`:285286- Тестовый модуль можно запускать автономно из командной строки.287- Тестовый код проще отделить от поставляемого кода.288- Меньше соблазна изменять тестовый код, чтобы подогнать его под тестируемый код, без веской причины.289- Тестовый код должен изменяться гораздо реже, чем тестируемый код.290- Тестируемый код проще поддаётся рефакторингу.291- Тесты для модулей, написанных на C, всё равно должны быть в отдельных модулях – так почему бы не придерживаться этого подхода?292- Если стратегия тестирования меняется, нет необходимости изменять исходный код.293294## Повторное использование старого тестового кода295296Некоторые пользователи обнаружат, что у них есть существующий тестовый код, который они хотели бы запустить из `unittest`, без преобразования каждой старой тестовой функции в подкласс [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase).297298По этой причине `unittest` предоставляет класс [`FunctionTestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.FunctionTestCase). Этот подкласс [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) можно использовать для обертывания существующей тестовой функции. Также можно предоставить функции настройки и завершения.299300Рассмотрим следующую тестовую функцию:301302```python303def testSomething():304 something = makeSomething()305 assert something.name is not None306 # ...307```308309можно создать эквивалентный экземпляр тестового случая следующим образом:310311```python312testcase = unittest.FunctionTestCase(testSomething)313```314315Если есть дополнительные методы настройки и очистки, которые должны вызываться в рамках работы тестового случая, их также можно предоставить следующим образом:316317```python318testcase = unittest.FunctionTestCase(testSomething,319 setUp=makeSomethingDB,320 tearDown=deleteSomethingDB)321```322323Чтобы облегчить миграцию существующих тестовых наборов, `unittest` поддерживает тесты, вызывающие [`AssertionError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.AssertionError) для указания неудачи теста. Однако рекомендуется вместо этого использовать явные методы `TestCase.fail*()` и `TestCase.assert*()`, так как будущие версии `unittest` могут обрабатывать [`AssertionError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.AssertionError) иначе.324325> **Примечание**326>327> Хотя [`FunctionTestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.FunctionTestCase) можно использовать для быстрого переноса существующей тестовой базы на систему на основе `unittest`, такой подход не рекомендуется. Потратив время на создание правильных подклассов [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase), вы сделаете будущий рефакторинг тестов намного проще.328329## Классы и функции330331#### `[unittest.TestCase]class unittest.TestCase([methodName])`332333Экземпляры класса [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) представляют наименьшие тестируемые единицы во вселенной `unittest`. Этот класс предназначен для использования в качестве базового класса, при этом конкретные тесты реализуются конкретными подклассами. Этот класс реализует интерфейс, необходимый исполнителю тестов для управления тестом, а также методы, которые тестовый код может использовать для проверки и сообщения о различных типах неудач.334335Каждый экземпляр [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) запускает один тестовый метод: метод с именем *methodName*. Как упоминалось ранее, был пример, выглядевший следующим образом:336337```python338def suite():339 suite = unittest.TestSuite()340 suite.addTest(WidgetTestCase('testDefaultSize'))341 suite.addTest(WidgetTestCase('testResize'))342 return suite343```344345Здесь создаются два экземпляра `WidgetTestCase`, каждый из которых выполняет один тест.346347*methodName* по умолчанию равно `'runTest'`.348349#### `[unittest.FunctionTestCase]class unittest.FunctionTestCase(testFunc[, setUp[, tearDown[, description]]])`350351Этот класс реализует часть интерфейса352353[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)354355, позволяющую тестовому раннеру управлять тестом, но не предоставляет методов, которые тестовый код может использовать для проверки и сообщения об ошибках. Это используется для создания тестовых примеров с использованием устаревшего тестового кода, что позволяет интегрировать его в тестовый фреймворк на основе356357`unittest`358359.360361#### `[unittest.TestSuite]class unittest.TestSuite([tests])`362363Этот класс представляет собой агрегацию отдельных тестовых случаев и тестовых наборов. Он предоставляет интерфейс, необходимый тестовому раннеру, чтобы его можно было запускать как любой другой тестовый случай. Запуск экземпляра [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) равносилен итерации по набору с запуском каждого теста по отдельности.364365Если задан *tests*, он должен быть итерабельным объектом, содержащим отдельные тестовые примеры или другие тестовые наборы, которые будут использоваться для первоначального построения набора. Дополнительные методы предоставляются для добавления тестовых примеров и наборов в коллекцию позже.366367#### `[unittest.TestLoader]class unittest.TestLoader`368369Этот класс отвечает за загрузку тестов в соответствии с различными критериями и возврат их упакованными в370371[`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite)372373. Он может загрузить все тесты в заданном модуле или подклассе374375[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)376377.378379#### `[unittest.TestResult]class unittest.TestResult`380381Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие – нет.382383#### `[unittest.defaultTestLoader]unittest.defaultTestLoader`384385Экземпляр класса386387[`TestLoader`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader)388389, предназначенный для совместного использования. Если настройка390391[`TestLoader`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader)392393не требуется, можно использовать этот экземпляр вместо многократного создания новых.394395#### `[unittest.TextTestRunner]class unittest.TextTestRunner([stream[, descriptions[, verbosity]]])`396397Базовая реализация исполнителя тестов, которая выводит результаты в стандартный поток ошибок. Она имеет несколько настраиваемых параметров, но в целом очень проста. Графические приложения, запускающие тестовые наборы, должны предоставлять альтернативные реализации.398399#### `[unittest.main]unittest.main([module[, defaultTest[, argv[, testRunner[, testLoader]]]]])`400401Командная программа, которая запускает набор тестов; это в первую очередь для того, чтобы сделать tестовые модули удобно исполняемыми. Простейшее использование этой функции – добавить следующую строку в конец тестового скрипта:402403```python404if __name__ == '__main__':405 unittest.main()406```407408Аргумент *testRunner* может быть либо классом тестового раннера, либо уже созданным экземпляром такого класса.409410В некоторых случаях существующие тесты могли быть написаны с использованием модуля [`doctest`](https://python-all.ru/3.0/library/doctest.html#module-doctest). В таком случае этот модуль предоставляет класс `DocTestSuite`, который может автоматически создавать экземпляры [`unittest.TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) из существующих тестов на основе [`doctest`](https://python-all.ru/3.0/library/doctest.html#module-doctest).411412## Объекты TestCase413414Каждый экземпляр [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) представляет отдельный тест, но каждый конкретный подкласс может использоваться для определения нескольких тестов – конкретный класс представляет отдельную тестовую фикстуру. Фикстура создаётся и очищается для каждого тестового случая.415416Экземпляры [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) предоставляют три группы методов: одна группа используется для запуска теста, другая – реализацией теста для проверки условий и сообщения об ошибках, а также несколько методов опроса, позволяющих получить информацию о самом тесте.417418Методы первой группы (выполнение теста):419420#### `[unittest.TestCase.setUp]TestCase.setUp()`421422Метод, вызываемый для подготовки тестовой фикстуры. Он вызывается непосредственно перед вызовом тестового метода; любое исключение, возбуждённое этим методом, будет считаться ошибкой, а не неудачей теста. Реализация по умолчанию ничего не делает.423424#### `[unittest.TestCase.tearDown]TestCase.tearDown()`425426Метод, вызываемый сразу после того, как тестовый метод был вызван и результат записан. Он вызывается, даже если тестовый метод возбудил исключение, поэтому реализация в подклассах должна быть особенно внимательной при проверке внутреннего состояния. Любое исключение, возбуждённое этим методом, будет считаться ошибкой, а не неудачей теста. Этот метод будет вызван только в случае успеха427428[`setUp()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.setUp)429430, независимо от результата тестового метода. Реализация по умолчанию ничего не делает.431432#### `[unittest.TestCase.run]TestCase.run([result])`433434Запускает тест, собирая результат в объект результата теста, переданный как *result*. Если *result* опущен или равен [`None`](https://python-all.ru/3.0/library/constants.html#None), создаётся временный объект результата (вызовом метода `defaultTestCase()`) и используется; этот объект результата не возвращается вызывающей стороне [`run()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.run).435436Того же эффекта можно добиться простым вызовом экземпляра [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase).437438#### `[unittest.TestCase.debug]TestCase.debug()`439440Запускает тест без сбора результата. Это позволяет исключениям, возбуждённым тестом, распространяться до вызывающей стороны и может использоваться для поддержки запуска тестов под отладчиком.441442Тестовый код может использовать любой из следующих методов для проверки и сообщения об ошибках.443444#### `[unittest.TestCase.assert_]TestCase.assert_(expr[, msg])`445446#### `TestCase.failUnless(expr[, msg])`447448#### `TestCase.assertTrue(expr[, msg])`449450Сигнализирует о неудаче теста, если451452*expr*453454ложно; пояснение к ошибке будет455456*msg*457458, если указано, иначе459460[`None`](https://python-all.ru/3.0/library/constants.html#None)461462.463464#### `[unittest.TestCase.assertEqual]TestCase.assertEqual(first, second[, msg])`465466#### `TestCase.failUnlessEqual(first, second[, msg])`467468Проверяет, что469470*first*471472и473474*second*475476равны. Если значения не равны, тест завершится ошибкой с пояснением, заданным в477478*msg*479480, или481482[`None`](https://python-all.ru/3.0/library/constants.html#None)483484. Обратите внимание, что использование485486[`failUnlessEqual()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.failUnlessEqual)487488предпочтительнее, чем сравнение в качестве первого параметра489490[`failUnless()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.failUnless)491492: значение по умолчанию для493494*msg*495496может быть вычислено так, чтобы включать представления обоих497498*first*499500и501502*second*503504.505506#### `[unittest.TestCase.assertNotEqual]TestCase.assertNotEqual(first, second[, msg])`507508#### `TestCase.failIfEqual(first, second[, msg])`509510Проверяет, что511512*first*513514и515516*second*517518не равны. Если значения равны, тест завершится ошибкой с пояснением, заданным в519520*msg*521522, или523524[`None`](https://python-all.ru/3.0/library/constants.html#None)525526. Обратите внимание, что использование527528[`failIfEqual()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.failIfEqual)529530предпочтительнее, чем сравнение в качестве первого параметра531532[`failUnless()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.failUnless)533534, поскольку значение по умолчанию для535536*msg*537538может быть вычислено так, чтобы включать представления обоих539540*first*541542и543544*second*545546.547548#### `[unittest.TestCase.assertAlmostEqual]TestCase.assertAlmostEqual(first, second[, places[, msg]])`549550#### `TestCase.failUnlessAlmostEqual(first, second[, places[, msg]])`551552Проверяет, что553554*first*555556и557558*second*559560приблизительно равны, вычисляя разность, округляя до заданного числа десятичных561562*знаков (places)*563564(по умолчанию 7) и сравнивая с нулём. Обратите внимание, что сравнение с заданным числом десятичных знаков – это не то же самое, что сравнение с заданным числом значащих цифр. Если значения не равны, тест завершится ошибкой с пояснением, заданным в565566*msg*567568, или569570[`None`](https://python-all.ru/3.0/library/constants.html#None)571572.573574#### `[unittest.TestCase.assertNotAlmostEqual]TestCase.assertNotAlmostEqual(first, second[, places[, msg]])`575576#### `TestCase.failIfAlmostEqual(first, second[, places[, msg]])`577578Проверяет, что579580*first*581582и583584*second*585586не являются приблизительно равными, вычисляя разность, округляя до заданного числа десятичных587588*знаков (places)*589590(по умолчанию 7) и сравнивая с нулём. Обратите внимание, что сравнение с заданным числом десятичных знаков – это не то же самое, что сравнение с заданным числом значащих цифр. Если значения не сравниваются как равные, тест завершится ошибкой с пояснением, заданным в591592*msg*593594, или595596[`None`](https://python-all.ru/3.0/library/constants.html#None)597598.599600#### `[unittest.TestCase.assertRaises]TestCase.assertRaises(exception, callable, ...)`601602#### `TestCase.failUnlessRaises(exception, callable, ...)`603604Проверяет, что исключение возбуждается при вызове605606*callable*607608с любыми позиционными или именованными аргументами, которые также передаются в609610[`assertRaises()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.assertRaises)611612. Тест проходит, если возбуждается613614*исключение*615616, считается ошибкой, если возбуждается другое исключение, или завершается неудачей, если не возбуждается ни одного исключения. Для перехвата любого из группы исключений в качестве617618*исключение*619620можно передать кортеж, содержащий классы исключений.621622#### `[unittest.TestCase.failIf]TestCase.failIf(expr[, msg])`623624#### `TestCase.assertFalse(expr[, msg])`625626Методом, обратным к627628[`failUnless()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.failUnless)629630, является метод631632[`failIf()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.failIf)633634. Он сигнализирует о сбое теста, если635636*expr*637638истинно, с639640*msg*641642или643644[`None`](https://python-all.ru/3.0/library/constants.html#None)645646в качестве сообщения об ошибке.647648#### `[unittest.TestCase.fail]TestCase.fail([msg])`649650Сигнализирует о сбое теста безусловно, с651652*msg*653654или655656[`None`](https://python-all.ru/3.0/library/constants.html#None)657658в качестве сообщения об ошибке.659660#### `[unittest.TestCase.failureException]TestCase.failureException`661662Этот атрибут класса задаёт исключение, вызываемое методом663664`test()`665666. Если тестовый фреймворк должен использовать специализированное исключение, возможно, для передачи дополнительной информации, он должен создать подкласс этого исключения, чтобы «играть по правилам» с фреймворком. Начальное значение этого атрибута –667668[`AssertionError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.AssertionError)669670.671672Тестовые фреймворки могут использовать следующие методы для сбора информации о тесте:673674#### `[unittest.TestCase.countTestCases]TestCase.countTestCases()`675676Возвращает количество тестов, представленных этим тестовым объектом. Для экземпляров677678[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)679680это значение всегда равно681682`1`683684.685686#### `[unittest.TestCase.defaultTestResult]TestCase.defaultTestResult()`687688Возвращает экземпляр класса результата теста, который следует использовать для данного класса тестового случая (если другой экземпляр результата не передан методу [`run()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.run)).689690Для экземпляров [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) это всегда будет экземпляром [`TestResult`](https://python-all.ru/3.0/library/unittest.html#unittest.TestResult); подклассы [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) должны переопределять это при необходимости.691692#### `[unittest.TestCase.id]TestCase.id()`693694Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя тестового метода, включая имя модуля и класса.695696#### `[unittest.TestCase.shortDescription]TestCase.shortDescription()`697698Возвращает однострочное описание теста или699700[`None`](https://python-all.ru/3.0/library/constants.html#None)701702, если описание не было предоставлено. Реализация по умолчанию этого метода возвращает первую строку docstring тестового метода, если она доступна, или703704[`None`](https://python-all.ru/3.0/library/constants.html#None)705706.707708## Объекты TestSuite709710Объекты [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) ведут себя во многом как объекты [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase), за исключением того, что они фактически не реализуют тест. Вместо этого они используются для объединения тестов в группы, которые должны выполняться вместе. Доступны некоторые дополнительные методы для добавления тестов в экземпляры [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite):711712#### `[unittest.TestSuite.addTest]TestSuite.addTest(test)`713714Добавляет объект715716[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)717718или719720[`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite)721722в набор.723724#### `[unittest.TestSuite.addTests]TestSuite.addTests(tests)`725726Добавляет все тесты из итерируемого объекта, содержащего экземпляры [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) и [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite), в данный тестовый набор.727728Это эквивалентно итерации по *tests* с вызовом [`addTest()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite.addTest) для каждого элемента.729730[`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) имеет общие следующие методы с [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase):731732#### `[unittest.TestSuite.run]TestSuite.run(result)`733734Запускает тесты, связанные с этим набором, собирая результат в объект результата теста, переданный как735736*result*737738. Обратите внимание, что в отличие от739740[`TestCase.run()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase.run)741742,743744[`TestSuite.run()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite.run)745746требует передачи объекта результата.747748#### `[unittest.TestSuite.debug]TestSuite.debug()`749750Запускает тесты, связанные с этим набором, без сбора результата. Это позволяет исключениям, вызванным тестом, распространяться до вызывающей стороны и может использоваться для поддержки запуска тестов под отладчиком.751752#### `[unittest.TestSuite.countTestCases]TestSuite.countTestCases()`753754Возвращает количество тестов, представленных этим тестовым объектом, включая все отдельные тесты и поднаборы.755756При типичном использовании объекта [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) метод `run()` вызывается `TestRunner`, а не тестовой обвязкой конечного пользователя.757758## Объекты TestResult759760Объект [`TestResult`](https://python-all.ru/3.0/library/unittest.html#unittest.TestResult) хранит результаты набора тестов. Классы [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) и [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) обеспечивают корректную запись результатов; авторам тестов не нужно беспокоиться о записи результатов тестов.761762Фреймворки для тестирования, построенные на основе `unittest`, могут нуждаться в доступе к объекту [`TestResult`](https://python-all.ru/3.0/library/unittest.html#unittest.TestResult), который создаётся при запуске набора тестов для отчётности; экземпляр [`TestResult`](https://python-all.ru/3.0/library/unittest.html#unittest.TestResult) возвращается методом `TestRunner.run()` для этой цели.763764Экземпляры [`TestResult`](https://python-all.ru/3.0/library/unittest.html#unittest.TestResult) имеют следующие атрибуты, которые будут интересны при просмотре результатов выполнения набора тестов:765766#### `[unittest.TestResult.errors]TestResult.errors`767768Список, содержащий кортежи из двух элементов: экземпляры769770[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)771772и строки с форматированными трассировками. Каждый кортеж представляет тест, вызвавший неожиданное исключение.773774#### `[unittest.TestResult.failures]TestResult.failures`775776Список, содержащий кортежи из двух элементов: экземпляры777778[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)779780и строки с отформатированными трассировками. Каждый кортеж представляет тест, в котором сбой был явно обозначен с помощью методов781782`TestCase.fail*()`783784или785786`TestCase.assert*()`787788.789790#### `[unittest.TestResult.testsRun]TestResult.testsRun`791792Общее количество запущенных на данный момент тестов.793794#### `[unittest.TestResult.wasSuccessful]TestResult.wasSuccessful()`795796Возвращает797798[`True`](https://python-all.ru/3.0/library/constants.html#True)799800, если все выполненные на данный момент тесты пройдены, иначе возвращает801802[`False`](https://python-all.ru/3.0/library/constants.html#False)803804.805806#### `[unittest.TestResult.stop]TestResult.stop()`807808Этот метод можно вызвать, чтобы указать, что набор выполняемых тестов следует прервать, установив атрибут `shouldStop` объекта [`TestResult`](https://python-all.ru/3.0/library/unittest.html#unittest.TestResult) в [`True`](https://python-all.ru/3.0/library/constants.html#True). Объекты `TestRunner` должны учитывать этот флаг и завершаться без выполнения дополнительных тестов.809810Например, эта возможность используется классом [`TextTestRunner`](https://python-all.ru/3.0/library/unittest.html#unittest.TextTestRunner) для остановки тестового фреймворка, когда пользователь подаёт сигнал прерывания с клавиатуры. Интерактивные инструменты, предоставляющие реализации `TestRunner`, могут использовать это аналогичным образом.811812Следующие методы класса [`TestResult`](https://python-all.ru/3.0/library/unittest.html#unittest.TestResult) используются для поддержки внутренних структур данных и могут быть расширены в подклассах для удовлетворения дополнительных требований к отчётности. Это особенно полезно при создании инструментов, поддерживающих интерактивную отчётность во время выполнения тестов.813814#### `[unittest.TestResult.startTest]TestResult.startTest(test)`815816Вызывается перед запуском тестового сценария *test*.817818Реализация по умолчанию просто увеличивает счётчик `testsRun` экземпляра.819820#### `[unittest.TestResult.stopTest]TestResult.stopTest(test)`821822Вызывается после выполнения тестового случая *test* независимо от результата.823824Реализация по умолчанию ничего не делает.825826#### `[unittest.TestResult.addError]TestResult.addError(test, err)`827828Вызывается, когда тестовый случай *test* вызывает неожиданное исключение. *err* – это кортеж вида, возвращаемого [`sys.exc_info()`](https://python-all.ru/3.0/library/sys.html#sys.exc_info): `(type, value, traceback)`.829830Реализация по умолчанию добавляет кортеж `(test, formatted_err)` в атрибут `errors` экземпляра, где *formatted\_err* – это отформатированная трассировка, полученная из *err*.831832#### `[unittest.TestResult.addFailure]TestResult.addFailure(test, err)`833834Вызывается, когда тестовый случай *test* сигнализирует о сбое. *err* – это кортеж вида, возвращаемого [`sys.exc_info()`](https://python-all.ru/3.0/library/sys.html#sys.exc_info): `(type, value, traceback)`.835836Реализация по умолчанию добавляет кортеж `(test, formatted_err)` в атрибут `failures` экземпляра, где *formatted\_err* – это отформатированная трассировка, полученная из *err*.837838#### `[unittest.TestResult.addSuccess]TestResult.addSuccess(test)`839840Вызывается, когда тестовый сценарий *test* завершается успешно.841842Реализация по умолчанию ничего не делает.843844## Объекты TestLoader845846Класс [`TestLoader`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader) используется для создания наборов тестов из классов и модулей. Обычно нет необходимости создавать экземпляр этого класса; модуль `unittest` предоставляет экземпляр, который можно использовать как `unittest.defaultTestLoader`. Однако использование подкласса или экземпляра позволяет настраивать некоторые параметры конфигурации.847848Объекты [`TestLoader`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader) имеют следующие методы:849850#### `[unittest.TestLoader.loadTestsFromTestCase]TestLoader.loadTestsFromTestCase(testCaseClass)`851852Возвращает набор всех тестовых случаев, содержащихся в классе853854`testCaseClass`855856, производном от857858[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)859860.861862#### `[unittest.TestLoader.loadTestsFromModule]TestLoader.loadTestsFromModule(module)`863864Возвращает набор всех тестовых случаев, содержащихся в указанном модуле. Этот метод ищет в *module* классы, производные от [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase), и создаёт экземпляр класса для каждого определённого в нём тестового метода.865866> **Предупреждение**867>868> Хотя использование иерархии классов, производных от [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase), может быть удобным для совместного использования фикстур и вспомогательных функций, определение тестовых методов в базовых классах, которые не предназначены для прямого создания экземпляров, плохо сочетается с этим методом. Однако это может быть полезно, когда фикстуры различаются и определяются в подклассах.869870#### `[unittest.TestLoader.loadTestsFromName]TestLoader.loadTestsFromName(name[, module])`871872Возвращает набор всех тестовых случаев по строковому спецификатору.873874Спецификатор *name* – это «точечное имя», которое может разрешаться в модуль, класс тестового случая, тестовый метод внутри класса тестового случая, экземпляр [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) или вызываемый объект, возвращающий экземпляр [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase) или [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite). Эти проверки применяются в указанном порядке; то есть метод в потенциальном классе тестового случая будет распознан как «тестовый метод внутри класса тестового случая», а не как «вызываемый объект».875876Например, если у вас есть модуль `SampleTests`, содержащий класс `SampleTestCase`, производный от [`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase), с тремя тестовыми методами (`test_one()`, `test_two()` и `test_three()`), то спецификатор `'SampleTests.SampleTestCase'` заставит этот метод вернуть набор, который выполнит все три тестовых метода. Использование спецификатора `'SampleTests.SampleTestCase.test_two'` приведёт к возврату набора тестов, который выполнит только тестовый метод `test_two()`. Спецификатор может ссылаться на модули и пакеты, которые ещё не были импортированы; они будут импортированы как побочный эффект.877878Метод опционально разрешает *name* относительно заданного *module*.879880#### `[unittest.TestLoader.loadTestsFromNames]TestLoader.loadTestsFromNames(names[, module])`881882Аналогично883884[`loadTestsFromName()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader.loadTestsFromName)885886, но принимает последовательность имён, а не одно имя. Возвращаемое значение – это набор тестов, который поддерживает все тесты, определённые для каждого имени.887888#### `[unittest.TestLoader.getTestCaseNames]TestLoader.getTestCaseNames(testCaseClass)`889890Возвращает отсортированную последовательность имён методов, найденных в891892*testCaseClass*893894; это должен быть подкласс895896[`TestCase`](https://python-all.ru/3.0/library/unittest.html#unittest.TestCase)897898.899900Следующие атрибуты [`TestLoader`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader) можно настроить либо через создание подкласса, либо присваиванием экземпляру:901902#### `[unittest.TestLoader.testMethodPrefix]TestLoader.testMethodPrefix`903904Строка, задающая префикс имён методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию – `'test'`.905906Это влияет на [`getTestCaseNames()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader.getTestCaseNames) и все методы `loadTestsFrom*()`.907908#### `[unittest.TestLoader.sortTestMethodsUsing]TestLoader.sortTestMethodsUsing`909910Функция для сравнения имён методов при сортировке в911912[`getTestCaseNames()`](https://python-all.ru/3.0/library/unittest.html#unittest.TestLoader.getTestCaseNames)913914и во всех методах915916`loadTestsFrom*()`917918. Эта функция должна принимать два аргумента:919920`self`921922и923924`other`925926, и возвращать927928`-1`929930, если931932`self`933934предшествует935936`other`937938в заданном порядке,939940`1`941942, если943944`other`945946предшествует947948`self`949950, и951952`0`953954, если955956`self`957958и959960`other`961962равны. По умолчанию используется встроенная сортировка строк. Этот атрибут также можно установить в963964[`None`](https://python-all.ru/3.0/library/constants.html#None)965966, чтобы отключить сортировку.967968#### `[unittest.TestLoader.suiteClass]TestLoader.suiteClass`969970Вызываемый объект, который создаёт тестовый набор из списка тестов. Никакие методы результирующего объекта не требуются. Значением по умолчанию является [`TestSuite`](https://python-all.ru/3.0/library/unittest.html#unittest.TestSuite) класс.971972Это влияет на все методы `loadTestsFrom*()`.973