unittest — Фреймворк для юнит-тестирования
Исходный код: Lib/unittest/__init__.py
(Если вы уже знакомы с основными понятиями тестирования, можете перейти к списку методов assert.)
Фреймворк для юнит-тестирования unittest первоначально был вдохновлён JUnit и имеет схожую структуру с основными фреймворками юнит-тестирования на других языках. Он поддерживает автоматизацию тестов, совместное использование кода подготовки и завершения для тестов, агрегацию тестов в коллекции и независимость тестов от фреймворка отчётности.
Для достижения этого, фреймворк unittest поддерживает некоторые важные концепции объектно-ориентированным способом:
- тестовый фикстур
-
Тестовый фикстур представляет подготовку, необходимую для выполнения одного или нескольких тестов, а также любые связанные действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск процесса сервера.
- тестовый случай
-
Тестовый случай — это отдельная единица тестирования. Он проверяет определённый ответ на конкретный набор входных данных.
unittestпредоставляет базовый классTestCase, который можно использовать для создания новых тестовых случаев. - тестовый набор
-
Тестовый набор — это коллекция тестовых случаев, тестовых наборов или обоих. Он используется для агрегации тестов, которые должны быть выполнены вместе.
- тестовый рантаймер
-
Тестовый рантаймер — это компонент, который организует выполнение тестов и предоставляет результат пользователю. Рантаймер может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение для указания результатов выполнения тестов.
См. также
-
Moduledoctest -
Другой модуль поддержки тестов с совершенно другим подходом.
- Simple Smalltalk Testing: With Patterns
-
Оригинальная статья Кента Бека о фреймворках тестирования, использующих шаблон, используемый в
unittest. - pytest
-
Фреймворк юнит-тестирования сторонних разработчиков с более лёгким синтаксисом для написания тестов. Например,
assert func(10) == 42. - Классификация инструментов тестирования Python
-
Развёрнутый список инструментов тестирования Python, включая фреймворки функционального тестирования и библиотеки объектов-моков.
- Список рассылки по тестированию в Python
-
Группа по интересам для обсуждения тестирования и инструментов тестирования в Python.
Скрипт Tools/unittestgui/unittestgui.py в дистрибутиве исходного кода Python — это инструмент графического интерфейса для обнаружения и выполнения тестов. Он предназначен главным образом для удобства использования новичками в юнит-тестировании. Для производственных сред рекомендуется использовать систему непрерывной интеграции, такую как Buildbot, Jenkins или Travis-CI, или AppVeyor.
Базовый пример
Модуль unittest предоставляет богатый набор инструментов для построения и запуска тестов. В этом разделе показано, что небольшого подмножества инструментов достаточно для удовлетворения потребностей большинства пользователей.
Вот небольшой скрипт для проверки трёх методов строк:
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
unittest.main()
Тестовый случай создаётся путём наследования от unittest.TestCase. Три отдельных теста определены методами, имена которых начинаются с букв test. Эта соглашение об именовании сообщает рантаймеру тестов о том, какие методы представляют собой тесты.
Суть каждого теста — вызов assertEqual() для проверки ожидаемого результата; assertTrue() или assertFalse() для проверки условия; или assertRaises() для проверки, что возникает конкретное исключение. Эти методы используются вместо оператора assert, чтобы рантаймер тестов мог накапливать все результаты тестов и генерировать отчёт.
Методы setUp() и tearDown() позволяют вам определить инструкции, которые будут выполняться до и после каждого тестового метода. Они более подробно описаны в разделе Организация кода тестов.
В последнем блоке показан простой способ запуска тестов. unittest.main() предоставляет интерфейс командной строки для тестового скрипта. При запуске из командной строки вышеприведённый скрипт выводит вывод, похожий на этот:
... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Передача параметра -v вашему тестовому скрипту даст указание unittest.main() включить более высокий уровень детализации и выведет следующий вывод:
test_isupper (__main__.TestStringMethods) ... ok test_split (__main__.TestStringMethods) ... ok test_upper (__main__.TestStringMethods) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
Приведённые выше примеры демонстрируют наиболее часто используемые возможности unittest, которые достаточно для решения многих повседневных задач тестирования. Остальная часть документации подробно рассматривает полный набор функций с оснований.
Интерфейс командной строки
Модуль unittest можно использовать из командной строки для запуска тестов из модулей, классов или даже отдельных тестовых методов:
python -m unittest test_module1 test_module2 python -m unittest test_module.TestClass python -m unittest test_module.TestClass.test_method
Вы можете передать список с любой комбинацией имён модулей и полных квалифицированных имён классов или методов.
Тестовые модули также можно указать по пути к файлу:
python -m unittest tests/test_something.py
Это позволяет использовать автодополнение имён файлов в оболочке для указания тестового модуля. Указанный файл по-прежнему должен быть импортируем как модуль. Путь преобразуется в имя модуля путём удаления «.py» и преобразования разделителей путей в «.». Если вы хотите выполнить тестовый файл, который не импортируется как модуль, вы должны выполнить файл непосредственно.
Вы можете запустить тесты с большей детализацией (более высоким уровнем подробности), передав флаг -v:
python -m unittest -v test_module
При выполнении без аргументов запускается Обнаружение тестов:
python -m unittest
Для получения списка всех опций командной строки:
python -m unittest -h
Изменено в версии 3.2: В предыдущих версиях можно было запускать только отдельные тестовые методы, а не модули или классы.
Опции командной строки
unittest поддерживает следующие опции командной строки:
-
-b, --buffer -
Стандартные потоки вывода и стандартные потоки ошибок буферизируются во время выполнения теста. Вывод во время успешного теста отбрасывается. Вывод отображается обычно при ошибке или сбое теста и добавляется к сообщениям об ошибках.
-
-c, --catch -
Ctrl-C во время выполнения теста ожидает завершения текущего теста, а затем сообщает все результаты до этого момента. Второй Ctrl-C вызывает обычное исключение
KeyboardInterrupt.См. Обработка сигналов для функций, которые предоставляют эту функциональность.
-
-f, --failfast -
Остановите выполнение теста при первой ошибке или сбое.
-
-k -
Запускать только те тестовые методы и классы, которые соответствуют шаблону или подстроке. Эта опция может быть использована несколько раз, в этом случае все тестовые случаи, которые соответствуют любому из заданных шаблонов, включаются.
Шаблоны, содержащие символ подстановки (
*), сопоставляются с именем теста с использованиемfnmatch.fnmatchcase(); в противном случае используется простое сопоставление подстрок, учитывающее регистр.Шаблоны сопоставляются с полным квалифицированным именем тестового метода, как импортировано загрузчиком тестов.
Например,
-k fooсоответствуетfoo_tests.SomeTest.test_something,bar_tests.SomeTest.test_foo, но неbar_tests.FooTest.test_something.
-
--locals -
Показать локальные переменные в отслеживании стека.
Добавлена в версии 3.2: Опции командной строки -b, -c и -f были добавлены.
Добавлена в версии 3.5: Опция командной строки --locals.
Добавлена в версии 3.7: Опция командной строки -k.
Командная строка также может использоваться для обнаружения тестов, для запуска всех тестов в проекте или только подмножества.
Обнаружение тестов
Добавлена в версии 3.2.
Unittest поддерживает простое обнаружение тестов. Для совместимости с обнаружением тестов все тестовые файлы должны быть модулями или пакетами (включая пакеты имён пространств), импортируемые из каталога верхнего уровня проекта (это означает, что их имена файлов должны быть допустимыми идентификаторами).
Обнаружение тестов реализовано в TestLoader.discover(), но также может использоваться из командной строки. Основное использование командной строки:
cd project_directory python -m unittest discover
Примечание
В качестве сокращения, python -m unittest эквивалентно python -m unittest discover. Если вы хотите передать аргументы в обнаружение тестов, discover подкоманда должна быть использована явно.
Подкоманда discover имеет следующие опции:
-
-v, --verbose -
Подробный вывод
-
-s, --start-directory directory -
Директория для начала обнаружения (
.по умолчанию)
-
-p, --pattern pattern -
Шаблон для сопоставления тестовых файлов (
test*.pyпо умолчанию)
-
-t, --top-level-directory directory -
Каталог верхнего уровня проекта (по умолчанию — текущий каталог)
Опции -s, -p и -t могут быть переданы в виде позиционных аргументов в указанном порядке. Следующие две командные строки эквивалентны:
python -m unittest discover -s project_directory -p "*_test.py" python -m unittest discover project_directory "*_test.py"
Помимо пути, можно передать имя пакета, например myproject.subpackage.test, как начальный каталог. Тогда имя пакета, которое вы предоставите, будет импортировано, и его расположение на файловой системе будет использоваться в качестве начального каталога.
Внимание
Обнаружение тестов загружает тесты путём их импорта. После того, как обнаружение тестов нашло все тестовые файлы из указанного вами начального каталога, оно преобразует пути в имена пакетов для импорта. Например, foo/bar/baz.py будет импортирован как foo.bar.baz.
Если у вас есть пакет, установленный глобально, и вы пытаетесь произвести обнаружение тестов на другой копии пакета, то импорт может произойти из неправильного места. Если это произойдёт, обнаружение тестов выведет предупреждение и завершит работу.
Если вы указываете начальный каталог как имя пакета, а не путь к каталогу, то обнаружение предполагает, что любая расположение, с которого производится импорт, является предполагаемым вами, поэтому предупреждение не будет выведено.
Тестовые модули и пакеты могут настраивать загрузку и обнаружение тестов с помощью протокола загрузки тестов.
Изменено в версии 3.4: Обнаружение тестов поддерживает пакеты имён пространств для начального каталога. Обратите внимание, что вам также необходимо указать каталог верхнего уровня (например, python -m unittest discover -s root/namespace -t root).
Организация тестового кода
Основными строительными блоками модульного тестирования являются тестовые случаи — отдельные сценарии, которые необходимо настроить и проверить на корректность. В unittest, тестовые случаи представлены экземплярами unittest.TestCase. Чтобы создать собственные тестовые случаи, необходимо написать подклассы TestCase или использовать FunctionTestCase.
Тестовый код экземпляра TestCase должен быть полностью самодостаточным, чтобы его можно было запускать изолированно или в произвольной комбинации с любым количеством других тестовых случаев.
Простейший подкласс TestCase просто реализует тестовый метод (т. е. метод, имя которого начинается с test) для выполнения определенного тестового кода:
import unittest
class DefaultWidgetSizeTestCase(unittest.TestCase):
def test_default_widget_size(self):
widget = Widget('The widget')
self.assertEqual(widget.size(), (50, 50))
Обратите внимание, что для тестирования чего-либо используется один из методов assert*() , предоставляемых базовым классом TestCase. Если тест завершается неудачей, будет поднято исключение с объяснительным сообщением, и unittest идентифицирует тестовый случай как неудачу. Любые другие исключения будут обрабатываться как ошибки.
Тестов может быть много, и их настройка может повторяться. К счастью, мы можем вынести код настройки, реализовав метод с именем setUp(), который тестовый фреймворк автоматически вызовет для каждого выполняемого теста:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def test_default_widget_size(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
def test_widget_resize(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
Примечание
Порядок выполнения различных тестов определяется сортировкой имён тестовых методов относительно встроенного порядка строк.
Если метод setUp() генерирует исключение во время выполнения теста, фреймворк сочтёт тест ошибочным, и тестовый метод не будет выполнен.
Аналогично, мы можем предоставить метод tearDown() для завершения работы после выполнения тестового метода:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
Если метод setUp() выполнился успешно, метод tearDown() будет выполнен независимо от того, выполнился ли тестовый метод успешно или нет.
Такая рабочая среда для тестового кода называется тестовым фикстуром. Новый экземпляр TestCase создается как уникальный тестовый фикстур, используемый для выполнения каждого отдельного тестового метода. Таким образом, setUp(), tearDown(), и __init__() будут вызываться один раз на тест.
Рекомендуется использовать реализации TestCase для группировки тестов по функциям, которые они тестируют. unittest предоставляет механизм для этого: тестовый набор, представленный классом unittest’s TestSuite. В большинстве случаев вызов unittest.main() сделает все правильно, собрав все тестовые случаи модуля и выполнив их.
Однако, если вы хотите настроить создание тестового набора, вы можете сделать это самостоятельно:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_widget_size'))
suite.addTest(WidgetTestCase('test_widget_resize'))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
Определения тестовых случаев и тестовых наборов можно размещать в тех же модулях, что и код, который они должны тестировать (например, widget.py), но есть несколько преимуществ размещения тестового кода в отдельном модуле, например, test_widget.py:
- Модуль тестов можно запускать автономно из командной строки.
- Тестовый код легче отделить от кода, который распространяется.
- Существует меньше соблазна изменять тестовый код, чтобы он соответствовал тестируемому коду без веских оснований.
- Тестовый код следует изменять значительно реже, чем код, который он тестирует.
- Тестируемый код можно легче перерабатывать.
- Тесты для модулей, написанных на C, должны быть в отдельных модулях, так почему бы не быть последовательными?
- Если стратегия тестирования меняется, нет необходимости изменять исходный код.
Переиспользование старого тестового кода
Некоторые пользователи могут обнаружить, что у них есть существующий тестовый код, который они хотели бы запускать из unittest, не преобразовывая каждый старый тестовый метод в подкласс TestCase.
По этой причине unittest предоставляет класс FunctionTestCase. Этот подкласс TestCase может использоваться для обертывания существующей тестовой функции. Также можно предоставить функции настройки и завершения.
Учитывая следующую тестовую функцию:
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
можно создать эквивалентный экземпляр тестового случая следующим образом, с необязательными методами настройки и завершения:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
Примечание
Несмотря на то, что FunctionTestCase можно использовать для быстрого перевода существующей тестовой базы в систему на основе unittest, этот подход не рекомендуется. Выделение времени на создание надлежащих подклассов TestCase сделает будущие рефакторинги тестов намного проще.
В некоторых случаях существующие тесты могут быть написаны с использованием модуля doctest. Если это так, doctest предоставляет класс DocTestSuite, который может автоматически создавать экземпляры unittest.TestSuite из существующих тестов на основе doctest.
Пропуск тестов и ожидаемые ошибки
Новая в версии 3.1.
Unittest поддерживает пропуск отдельных тестовых методов и даже целых классов тестов. Кроме того, он поддерживает пометку теста как «ожидаемой ошибки» — это тест, который сломан и даст сбой, но не должен учитываться как сбой в TestResult.
Пропуск теста осуществляется просто с помощью skip() декоратора или одного из его условных вариантов, вызова TestCase.skipTest() внутри setUp() или тестового метода, или поднятия SkipTest непосредственно.
Базовый пропуск выглядит так:
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
def test_maybe_skipped(self):
if not external_resource_available():
self.skipTest("external resource not available")
# test code that depends on the external resource
pass
Это вывод выполнения примера выше в режиме подробной информации:
test_format (__main__.MyTestCase) ... skipped 'not supported in this library version' test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping' test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available' test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows' ---------------------------------------------------------------------- Ran 4 tests in 0.005s OK (skipped=4)
Классы могут пропускаться так же, как и методы:
@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
def test_not_run(self):
pass
TestCase.setUp() также может пропустить тест. Это полезно, когда ресурс, который нужно настроить, недоступен.
Ожидаемые ошибки используют декоратор expectedFailure().
class ExpectedFailureTestCase(unittest.TestCase):
@unittest.expectedFailure
def test_fail(self):
self.assertEqual(1, 0, "broken")
Легко создавать собственные декораторы пропуска, создавая декоратор, который вызывает skip() для теста, когда нужно его пропустить. Этот декоратор пропускает тест, если у переданного объекта есть определенный атрибут:
def skipUnlessHasattr(obj, attr):
if hasattr(obj, attr):
return lambda func: func
return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))
Следующие декораторы и исключения реализуют пропуск тестов и ожидаемые ошибки:
-
@unittest.skip(reason) -
Безусловно пропускает декорированный тест. reason должно описывать причину пропуска теста.
-
@unittest.skipIf(condition, reason) -
Пропускает декорированный тест, если condition истинно.
-
@unittest.skipUnless(condition, reason) -
Пропускает декорированный тест, если condition ложно.
-
@unittest.expectedFailure -
Помечает тест как ожидаемую ошибку или исключение. Если тест завершается сбоем или ошибкой в самой функции теста (а не в одном из методов настроек теста), то он считается успешным. Если тест проходит, он считается ошибочным.
-
exception unittest.SkipTest(reason) -
Это исключение поднимается для пропуска теста.
Обычно можно использовать
TestCase.skipTest()или один из декораторов пропуска, а не поднимать это напрямую.
Пропущенные тесты не будут выполнять setUp() или tearDown() вокруг них. Пропущенные классы не будут выполнять setUpClass() или tearDownClass(). Пропущенные модули не будут выполнять setUpModule() или tearDownModule().
Различение итераций тестов с помощью подтестов
Новая в версии 3.4.
Когда между вашими тестами есть очень небольшие различия, например, некоторые параметры, unittest позволяет различать их внутри тела тестового метода, используя контекстный менеджер subTest().
Например, следующий тест:
class NumbersTest(unittest.TestCase):
def test_even(self):
"""
Test that numbers between 0 and 5 are all even.
"""
for i in range(0, 6):
with self.subTest(i=i):
self.assertEqual(i % 2, 0)
выведет следующий вывод:
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=3)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=5)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
Без использования подтеста выполнение остановится после первой ошибки, и ошибка будет менее легко диагностирована, потому что значение i не будет отображено:
======================================================================
FAIL: test_even (__main__.NumbersTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
Классы и функции
В этом разделе подробно описан API unittest.
Объекты тестовых случаев
-
class unittest.TestCase(methodName='runTest') -
Экземпляры класса
TestCaseпредставляют собой логические тестовые единицы во вселеннойunittest. Этот класс предназначен для использования в качестве базового класса, при этом конкретные тесты реализуются в производных классах. Этот класс реализует интерфейс, необходимый исполнителю тестов для управления тестами, и методы, которые код теста может использовать для проверки и отчёта о различных типах сбоев.Каждый экземпляр
TestCaseвыполнит один базовый метод: метод с именем methodName. В большинстве случаев использованияTestCase, вы не будете изменять methodName и не будете переопределять метод по умолчаниюrunTest().Изменено в версии 3.2:
TestCaseможет быть успешно создан без предоставления methodName. Это упрощает экспериментирование сTestCaseиз интерактивного интерпретатора.Экземпляры
TestCaseпредоставляют три группы методов: одна группа для запуска теста, другая для проверки условий и отчёта о сбоях реализацией теста, и некоторые методы запросов, позволяющие собирать информацию о самом тесте.Методы первой группы (запуск теста):
-
setUp() -
Метод, вызываемый для подготовки тестового фикстура. Он вызывается непосредственно перед вызовом тестового метода; любое исключение, кроме
AssertionErrorилиSkipTest, которое возникает в этом методе, будет рассматриваться как ошибка, а не как сбой теста. По умолчанию метод ничего не делает.
-
tearDown() -
Метод, вызываемый сразу после того, как был вызван тестовый метод и был записан результат. Он вызывается даже если тестовый метод поднял исключение, поэтому реализация в производных классах должна быть особенно внимательной к проверке внутреннего состояния. Любое исключение, кроме
AssertionErrorилиSkipTest, которое возникает в этом методе, будет рассматриваться как дополнительная ошибка, а не как сбой теста (тем самым увеличивая общее количество сообщённых ошибок). Этот метод будет вызван только в случае успешного выполненияsetUp(), независимо от результата выполнения тестового метода. По умолчанию метод ничего не делает.
-
setUpClass() -
Метод класса, вызываемый перед запуском тестов в отдельном классе.
setUpClassвызывается с классом в качестве единственного аргумента и должен быть помечен какclassmethod():@classmethod def setUpClass(cls): ...См. Фикстуры классов и модулей для получения дополнительной информации.
Введено в версии 3.2.
-
tearDownClass() -
Метод класса, вызываемый после запуска тестов в отдельном классе.
tearDownClassвызывается с классом в качестве единственного аргумента и должен быть помечен какclassmethod():@classmethod def tearDownClass(cls): ...См. Фикстуры классов и модулей для получения дополнительной информации.
Введено в версии 3.2.
-
run(result=None) -
Запустить тест, собрав результат в объект
TestResult, переданный в качестве result. Если result опущен илиNone, создаётся временный объект результата (вызывая методdefaultTestResult()) и используется. Объект результата возвращается вызывающей стороне методаrun().То же самое можно сделать, просто вызвав экземпляр
TestCase.Изменено в версии 3.3: Предыдущие версии
runне возвращали результат. То же самое не происходило при вызове экземпляра.
-
skipTest(reason) -
Вызов этого во время метода теста или
setUp()пропускает текущий тест. См. Пропуск тестов и ожидаемые сбои для получения дополнительной информации.Введено в версии 3.1.
-
subTest(msg=None, **params) -
Возвращает менеджер контекста, который выполняет заключённый блок кода в качестве подтеста. msg и params являются необязательными произвольными значениями, которые отображаются всякий раз, когда подтест завершается неудачей, что позволяет чётко их идентифицировать.
Тестовый случай может содержать любое количество объявлений подтестов, и они могут быть произвольным образом вложены.
См. Различение итераций тестов с помощью подтестов для получения дополнительной информации.
Введено в версии 3.4.
-
debug() -
Запустить тест без сбора результата. Это позволяет исключениям, возникающим в тесте, распространяться к вызывающему методу и может быть использовано для поддержки запуска тестов под отладчиком.
Класс
TestCaseпредоставляет несколько методов утверждений для проверки и отчёта о сбоях. В следующей таблице перечислены наиболее часто используемые методы (см. таблицы ниже для получения более подробной информации о методах утверждений):Метод
Проверяет, что
Введено в
a == ba != bbool(x) is Truebool(x) is Falsea is b3.1
a is not b3.1
x is None3.1
x is not None3.1
a in b3.1
a not in b3.1
isinstance(a, b)3.2
not isinstance(a, b)3.2
Все методы утверждений принимают аргумент msg, который, если указан, используется в качестве сообщения об ошибке при ошибке (см. также
longMessage). Обратите внимание, что аргумент msg может быть передан вassertRaises(),assertRaisesRegex(),assertWarns(),assertWarnsRegex()только при использовании их как менеджера контекста. -
-
assertEqual(first, second, msg=None) -
Проверка, что first и second равны. Если значения не равны, тест завершится с ошибкой.
Кроме того, если first и second имеют тот же тип и являются списком, кортежем, словарем, множеством, замороженным множеством или строкой, или любым типом, который подкласс регистрирует с помощью
addTypeEqualityFunc(), будет вызвана функция сравнения, специфичная для типа, чтобы сгенерировать более полезное сообщение об ошибке (см. также список методов, специфичных для типов).Изменено в версии 3.1: Добавлена автоматическая вызов функции сравнения, специфичной для типа.
Изменено в версии 3.2:
assertMultiLineEqual()добавлена в качестве функции сравнения по умолчанию для сравнения строк.
-
assertNotEqual(first, second, msg=None) -
Проверка, что first и second не равны. Если значения равны, тест завершится с ошибкой.
-
assertTrue(expr, msg=None) -
assertFalse(expr, msg=None) -
Проверка, что expr истинно (или ложно).
Обратите внимание, что это эквивалентно
bool(expr) is Trueи не эквивалентноexpr is True(для последнего используйтеassertIs(expr, True)). Следует избегать этого метода, когда доступны более специфичные методы (например,assertEqual(a, b)вместоassertTrue(a == b)), так как они обеспечивают более подробное сообщение об ошибке в случае неудачи.
-
assertIs(first, second, msg=None) -
assertIsNot(first, second, msg=None) -
Проверка, что first и second являются (или не являются) одним и тем же объектом.
Введено в версии 3.1.
-
assertIsNone(expr, msg=None) -
assertIsNotNone(expr, msg=None) -
Проверка, что expr является (или не является)
None.Введено в версии 3.1.
-
assertIn(member, container, msg=None) -
assertNotIn(member, container, msg=None) -
Проверка, что member содержится (или не содержится) в container.
Введено в версии 3.1.
-
assertIsInstance(obj, cls, msg=None) -
assertNotIsInstance(obj, cls, msg=None) -
Проверка, что obj является (или не является) экземпляром cls (который может быть классом или кортежем классов, как поддерживается
isinstance()). Для проверки точного типа используйтеassertIs(type(obj), cls).Введено в версии 3.2.
Также возможно проверить возникновение исключений, предупреждений и сообщений в журнал, используя следующие методы:
Метод
Проверяет, что
Введено в
fun(*args, **kwds)вызывает excfun(*args, **kwds)вызывает exc и сообщение соответствует регулярному выражению r3.1
fun(*args, **kwds)вызывает warn3.2
fun(*args, **kwds)вызывает warn и сообщение соответствует регулярному выражению r3.2
Блок
withзаписывает в журнал logger с минимальным уровнем level3.4
-
The with block does not log on -
logger с минимальным уровнем level
3.10
-
assertRaises(exception, callable, *args, **kwds) -
assertRaises(exception, *, msg=None) -
Проверка, что исключение возникает при вызове callable с любыми позиционными или ключевыми аргументами, которые также передаются в
assertRaises(). Тест проходит, если exception возникает, является ошибкой, если возникает другое исключение, или терпит неудачу, если исключение не возникает. Для перехвата любой группы исключений можно передать кортеж содержащий классы исключений как exception.Если заданы только аргументы exception и, возможно, msg, возвращается менеджер контекста, чтобы код, который тестируется, можно было написать встроеным образом, а не как функцию:
with self.assertRaises(SomeException): do_something()При использовании в качестве менеджера контекста,
assertRaises()принимает дополнительный ключевой аргумент msg.Менеджер контекста будет хранить пойманный объект исключения в своем
exceptionатрибуте. Это может быть полезно, если нужно выполнить дополнительные проверки на поднятом исключении:with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3)Изменено в версии 3.1: Добавлена возможность использования
assertRaises()в качестве менеджера контекста.Изменено в версии 3.2: Добавлен атрибут
exception.Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
assertRaisesRegex(exception, regex, callable, *args, **kwds) -
assertRaisesRegex(exception, regex, *, msg=None) -
Как
assertRaises(), но также проверяет, что regex соответствует строковому представлению поднятого исключения. regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования сre.search(). Примеры:self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$", int, 'XYZ')или:
with self.assertRaisesRegex(ValueError, 'literal'): int('XYZ')Введено в версии 3.1: Добавлен под названием
assertRaisesRegexp.Изменено в версии 3.2: Переименовано в
assertRaisesRegex().Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
assertWarns(warning, callable, *args, **kwds) -
assertWarns(warning, *, msg=None) -
Проверка, что предупреждение вызывается, когда callable вызывается с любыми позиционными или ключевыми аргументами, которые также передаются в
assertWarns(). Тест проходит, если warning сгенерировано и терпит неудачу, если нет. Любое исключение является ошибкой. Для перехвата любой группы предупреждений можно передать кортеж, содержащий классы предупреждений как warnings.Если заданы только аргументы warning и, возможно, msg, возвращается менеджер контекста, чтобы код, который тестируется, можно было написать встроеным образом, а не как функцию:
with self.assertWarns(SomeWarning): do_something()При использовании в качестве менеджера контекста,
assertWarns()принимает дополнительный ключевой аргумент msg.Менеджер контекста сохранит пойманный объект предупреждения в своем
warningатрибуте и строку источника, которая вызвала предупреждение, вfilenameиlinenoатрибутах. Это может быть полезно, если нужно выполнить дополнительные проверки на пойманном предупреждении:with self.assertWarns(SomeWarning) as cm: do_something() self.assertIn('myfile.py', cm.filename) self.assertEqual(320, cm.lineno)Этот метод работает независимо от фильтров предупреждений, установленных во время его вызова.
Введено в версии 3.2.
Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
-
assertWarnsRegex(warning, regex, callable, *args, **kwds) -
assertWarnsRegex(warning, regex, *, msg=None) -
Подобно
assertWarns(), но также проверяет, что regex соответствует сообщению сгенерированного предупреждения. regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования сre.search(). Пример:self.assertWarnsRegex(DeprecationWarning, r'legacy_function\(\) is deprecated', legacy_function, 'XYZ')или:
with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'): frobnicate('/etc/passwd')Новая функция в версии 3.2.
Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
assertLogs(logger=None, level=None) -
Менеджер контекста для проверки того, что по крайней мере одно сообщение зарегистрировано в logger или одном из его дочерних логгеров, с указанным level.
Если задано, logger должен быть объектом
logging.Loggerили строкой, содержащей имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения, не заблокированные дочерним логгером, который не поддерживает распространение.Если задано, level должен быть либо числовым уровнем логирования, либо его строковым эквивалентом (например, либо
"ERROR"либоlogging.ERROR). По умолчаниюlogging.INFO.Тест пройден, если по крайней мере одно сообщение, выпущенное внутри блока
with, соответствует условиям logger и level; в противном случае тест провален.Объект, возвращаемый менеджером контекста, — это вспомогательный объект записи, который отслеживает соответствующие сообщения в логах. У него есть два атрибута:
-
records -
Список объектов
logging.LogRecordсоответствующих сообщений в логах.
-
output -
Список объектов
strс отформатированным выводом соответствующих сообщений.
Пример:
with self.assertLogs('foo', level='INFO') as cm: logging.getLogger('foo').info('first message') logging.getLogger('foo.bar').error('second message') self.assertEqual(cm.output, ['INFO:foo:first message', 'ERROR:foo.bar:second message'])Новая функция в версии 3.4.
-
-
assertNoLogs(logger=None, level=None) -
Менеджер контекста для проверки того, что сообщения не регистрируются в logger или одном из его дочерних логгеров, с указанным level.
Если задано, logger должен быть объектом
logging.Loggerили строкой, содержащей имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения.Если задано, level должен быть либо числовым уровнем логирования, либо его строковым эквивалентом (например, либо
"ERROR"либоlogging.ERROR). По умолчаниюlogging.INFO.В отличие от
assertLogs(), менеджер контекста ничего не вернет.Новая функция в версии 3.10.
Существуют и другие методы для более точной проверки, такие как:
Метод
Проверяет
В версии
round(a-b, 7) == 0round(a-b, 7) != 0a > b3.1
a >= b3.1
a < b3.1
a <= b3.1
r.search(s)3.1
not r.search(s)3.2
a и b содержат одинаковые элементы в одинаковом количестве, независимо от их порядка.
3.2
-
assertAlmostEqual(first, second, places=7, msg=None, delta=None) -
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None) -
Проверка, что first и second приблизительно (или не приблизительно) равны, вычисляя разницу, округляя до заданного количества десятичных знаков (по умолчанию 7) и сравнивая с нулем. Обратите внимание, что эти методы округляют значения до заданного количества десятичных знаков (как функция
round()), а не значимых цифр.Если вместо places задан delta, то разница между first и second должна быть меньше или равна (или больше) delta.
Задавать одновременно delta и places приведёт к ошибке
TypeError.Изменено в версии 3.2:
assertAlmostEqual()автоматически считает объекты приблизительно равными, если они сравниваются как равные.assertNotAlmostEqual()автоматически завершается ошибкой, если объекты сравниваются как равные. Добавлен ключевой аргумент delta.
-
assertGreater(first, second, msg=None) -
assertGreaterEqual(first, second, msg=None) -
assertLess(first, second, msg=None) -
assertLessEqual(first, second, msg=None) -
Проверка того, что first соответственно >, >=, < или <= second в зависимости от имени метода. Если нет, тест провален:
>>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4"
Новая функция в версии 3.1.
-
assertRegex(text, regex, msg=None) -
assertNotRegex(text, regex, msg=None) -
Проверка того, что поиск по regex соответствует (или не соответствует) text. В случае ошибки сообщение об ошибке будет содержать шаблон и text (или шаблон и часть text, которая неожиданно совпала). regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования с
re.search().Новая функция в версии 3.1: Добавлена под именем
assertRegexpMatches.Изменено в версии 3.2: Метод
assertRegexpMatches()переименован вassertRegex().Новая функция в версии 3.2:
assertNotRegex().Новая функция в версии 3.5: Имя
assertNotRegexpMatches— устаревшее псевдоним дляassertNotRegex().
-
assertCountEqual(first, second, msg=None) -
Проверка, что последовательность first содержит те же элементы, что и second, независимо от их порядка. Если нет, будет сгенерировано сообщение об ошибке, перечисляющее различия между последовательностями.
Дубликаты элементов не игнорируются при сравнении first и second. Проверяется, что каждый элемент встречается в обеих последовательностях одинаковое количество раз. Эквивалентно:
assertEqual(Counter(list(first)), Counter(list(second))), но работает и с последовательностями нехешируемых объектов.Новая функция в версии 3.2.
Метод
assertEqual()перенаправляет проверку равенства объектов одного типа на разные методы, специфичные для типа. Эти методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы, используяaddTypeEqualityFunc():-
-
addTypeEqualityFunc(typeobj, function) -
Регистрирует метод, специфичный для типа, вызываемый
assertEqual()для проверки, равны ли два объекта ровно того же типа typeobj (а не подклассов). function должен принимать два позиционных аргумента и необязательный аргумент msg=None, точно так же, как иassertEqual(). Он должен вызывать исключениеself.failureException(msg), когда обнаруживается неравенство между первыми двумя параметрами — возможно, предоставляя полезную информацию и объясняя неравенства подробно в сообщении об ошибке.Введено в версии 3.1.
Список методов, специфичных для типа, которые автоматически используются
assertEqual(), приведен в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать эти методы напрямую.Метод
Используется для сравнения
Введено в
строки
3.1
последовательности
3.1
списки
3.1
кортежи
3.1
множества или неизменяемые множества
3.1
словари
3.1
-
assertMultiLineEqual(first, second, msg=None) -
Проверка, что многострочная строка first равна строке second. При неравенстве в сообщение об ошибке будет включена разница между двумя строками с выделением отличий. Этот метод используется по умолчанию при сравнении строк с
assertEqual().Введено в версии 3.1.
-
assertSequenceEqual(first, second, msg=None, seq_type=None) -
Проверяет, что две последовательности равны. Если указан seq_type, то first и second должны быть экземплярами seq_type, иначе будет поднято исключение. Если последовательности отличаются, строится сообщение об ошибке, которое показывает разницу между ними.
Этот метод не вызывается напрямую
assertEqual(), но он используется для реализацииassertListEqual()иassertTupleEqual().Введено в версии 3.1.
-
assertListEqual(first, second, msg=None) -
assertTupleEqual(first, second, msg=None) -
Проверяет, что два списка или кортежа равны. Если нет, строится сообщение об ошибке, которое показывает только различия между ними. Возникает ошибка, если какой-либо из параметров имеет неправильный тип. Эти методы используются по умолчанию при сравнении списков или кортежей с
assertEqual().Введено в версии 3.1.
-
assertSetEqual(first, second, msg=None) -
Проверяет, что два множества равны. Если нет, строится сообщение об ошибке, которое показывает различия между множествами. Этот метод используется по умолчанию при сравнении множеств или неизменяемых множеств с
assertEqual().Возникает ошибка, если у first или second нет метода
set.difference().Введено в версии 3.1.
-
assertDictEqual(first, second, msg=None) -
Проверяет, что два словаря равны. Если нет, строится сообщение об ошибке, показывающее различия в словарях. Этот метод будет использоваться по умолчанию для сравнения словарей в вызовах
assertEqual().Введено в версии 3.1.
Наконец,
TestCaseпредоставляет следующие методы и атрибуты:-
fail(msg=None) -
Безусловно сигнализирует об ошибке теста с сообщением msg или
None.
-
failureException -
Этот атрибут класса задаёт исключение, поднимаемое методом теста. Если тестовой структуре необходимо использовать специализированное исключение, возможно для переноса дополнительной информации, она должна наследовать от этого исключения, чтобы «играть по правилам» структуры. Начальное значение этого атрибута —
AssertionError.
-
longMessage -
Этот атрибут класса определяет, что происходит, когда пользовательское сообщение об ошибке передаётся как аргумент msg в вызов assertXYY, который завершается ошибкой. Значение по умолчанию —
True. В этом случае пользовательское сообщение добавляется в конец стандартного сообщения об ошибке. При значенииFalse, пользовательское сообщение заменяет стандартное сообщение.Настройка класса может быть переопределена в отдельных методах тестирования присвоением атрибута экземпляра self.longMessage значения
TrueилиFalseперед вызовом методов assert.Настройка класса сбрасывается перед каждым вызовом теста.
Введено в версии 3.1.
-
maxDiff -
Этот атрибут контролирует максимальную длину выводимых различий методами assert, которые отображают различия при ошибке. По умолчанию 80*8 символов. Методы assert, затронутые этим атрибутом, —
assertSequenceEqual()(включая все методы сравнения последовательностей, которые делегируют ему),assertDictEqual()иassertMultiLineEqual().Установление значения
maxDiffвNoneозначает, что нет максимальной длины различий.Введено в версии 3.2.
Тестовые структуры могут использовать следующие методы для сбора информации о тесте:
-
countTestCases() -
Возвращает количество тестов, представленных этим объектом теста. Для экземпляров
TestCaseэто всегда1.
-
defaultTestResult() -
Возвращает экземпляр класса результатов теста, который должен использоваться для этого класса тестового случая (если другой экземпляр результатов не предоставлен методу
run()).Для экземпляров
TestCaseэто всегда будет экземплярTestResult; подклассыTestCaseдолжны переопределять это при необходимости.
-
id() -
Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя метода теста, включая имя модуля и класса.
-
shortDescription() -
Возвращает описание теста или
Noneесли описание не предоставлено. Реализация по умолчанию возвращает первую строку документации метода теста, если она доступна, илиNone.Изменено в версии 3.1: В 3.1 это было изменено для добавления имени теста в краткое описание даже при наличии документации. Это вызвало проблемы совместимости с расширениями unittest, и добавление имени теста было перенесено в
TextTestResultв Python 3.2.
-
-
addCleanup(function, /, *args, **kwargs) -
Добавить функцию, которая будет вызвана после
tearDown()для очистки ресурсов, используемых во время теста. Функции будут вызваны в обратном порядке к порядку их добавления (LIFO). Они вызываются с любыми аргументами и именованными аргументами, переданными вaddCleanup()при их добавлении.Если
setUp()завершится ошибкой, что означает, чтоtearDown()не будет вызван, любые добавленные функции очистки всё равно будут вызваны.Новая в версии 3.1.
-
doCleanups() -
Этот метод вызывается безусловно после
tearDown()или послеsetUp(), еслиsetUp()вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных с помощью
addCleanup(). Если вам нужно, чтобы функции очистки вызывались доtearDown(), вы можете вызватьdoCleanups()самостоятельно.doCleanups()извлекает методы из стека функций очистки по одному, поэтому его можно вызвать в любое время.Новая в версии 3.1.
-
classmethod addClassCleanup(function, /, *args, **kwargs) -
Добавить функцию, которая будет вызвана после
tearDownClass()для очистки ресурсов, используемых в классе тестов. Функции будут вызваны в обратном порядке к порядку их добавления (LIFO). Они вызываются с любыми аргументами и именованными аргументами, переданными вaddClassCleanup()при их добавлении.Если
setUpClass()завершится ошибкой, что означает, чтоtearDownClass()не будет вызван, любые добавленные функции очистки всё равно будут вызваны.Новая в версии 3.8.
-
classmethod doClassCleanups() -
Этот метод вызывается безусловно после
tearDownClass()или послеsetUpClass(), еслиsetUpClass()вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных с помощью
addClassCleanup(). Если вам нужно, чтобы функции очистки вызывались доtearDownClass(), вы можете вызватьdoClassCleanups()самостоятельно.doClassCleanups()извлекает методы из стека функций очистки по одному, поэтому его можно вызвать в любое время.Новая в версии 3.8.
-
-
class unittest.IsolatedAsyncioTestCase(methodName='runTest') -
Этот класс предоставляет API, аналогичный
TestCase, и также принимает корутины в качестве функций тестов.Новая в версии 3.8.
-
coroutine asyncSetUp() -
Метод, вызываемый для подготовки фикстуры теста. Вызывается после
setUp(). Вызывается непосредственно перед вызовом метода теста; любое исключение, кромеAssertionErrorилиSkipTest, которое вызывает этот метод, будет рассматриваться как ошибка, а не как сбой теста. По умолчанию ничего не делает.
-
coroutine asyncTearDown() -
Метод, вызываемый непосредственно после вызова метода теста и записи результата. Вызывается перед
tearDown(). Вызывается даже если метод теста вызвал исключение, поэтому реализация в подклассах должна быть особенно внимательной к проверке внутреннего состояния. Любое исключение, кромеAssertionErrorилиSkipTest, которое вызывает этот метод, будет рассматриваться как дополнительная ошибка, а не как сбой теста (тем самым увеличивая общее количество сообщённых ошибок). Этот метод будет вызван только в том случае, еслиasyncSetUp()успешно выполнится, независимо от результата метода теста. По умолчанию ничего не делает.
-
addAsyncCleanup(function, /, *args, **kwargs) -
Этот метод принимает корутину, которая может использоваться как функция очистки.
-
run(result=None) -
Создаёт новую событийную петлю для выполнения теста, собирая результат в объект
TestResult, переданный как result. Если result опущен илиNone, создаётся временный объект результата (вызывая методdefaultTestResult()) и используется. Объект результата возвращается вызывающей сторонеrun(). В конце теста все задачи в событийной петле отменяются.
Пример, иллюстрирующий порядок:
from unittest import IsolatedAsyncioTestCase events = [] class Test(IsolatedAsyncioTestCase): def setUp(self): events.append("setUp") async def asyncSetUp(self): self._async_connection = await AsyncConnection() events.append("asyncSetUp") async def test_response(self): events.append("test_response") response = await self._async_connection.get("https://example.com") self.assertEqual(response.status_code, 200) self.addAsyncCleanup(self.on_cleanup) def tearDown(self): events.append("tearDown") async def asyncTearDown(self): await self._async_connection.close() events.append("asyncTearDown") async def on_cleanup(self): events.append("cleanup") if __name__ == "__main__": unittest.main()После выполнения теста,
eventsбудет содержать["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]. -
-
class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None) -
Этот класс реализует часть интерфейса
TestCase, которая позволяет исполнителю тестов управлять тестом, но не предоставляет методы, которые код теста может использовать для проверки и отчёта об ошибках. Он используется для создания тестовых случаев, используя код старых тестов, позволяя интегрировать его в фреймворк тестов, основанный наunittest.
Устаревшие псевдонимы
По историческим причинам некоторые методы TestCase имели один или несколько устаревших псевдонимов. В следующей таблице перечислены правильные имена вместе с их устаревшими псевдонимами:
Имя метода | Устаревший псевдоним | Устаревший псевдоним |
|---|---|---|
failUnlessEqual | assertEquals | |
failIfEqual | assertNotEquals | |
failUnless | assert_ | |
failIf | ||
failUnlessRaises | ||
failUnlessAlmostEqual | assertAlmostEquals | |
failIfAlmostEqual | assertNotAlmostEquals | |
assertRegexpMatches | ||
assertNotRegexpMatches | ||
assertRaisesRegexp |
Устарело начиная с версии 3.1: Псевдонимы fail* в втором столбце устарели.
Устарело начиная с версии 3.2: Псевдонимы assert* в третьем столбце устарели.
Устарело начиная с версии 3.2: assertRegexpMatches и assertRaisesRegexp были переименованы в assertRegex() и assertRaisesRegex().
Устарело начиная с версии 3.5: Имя assertNotRegexpMatches устарело в пользу assertNotRegex().
Группировка тестов
-
class unittest.TestSuite(tests=()) -
Этот класс представляет собой агрегацию отдельных тестовых случаев и наборов тестов. Класс предоставляет интерфейс, необходимый для запуска тестов, чтобы позволить ему запускаться как любой другой тестовый случай. Запуск экземпляра
TestSuiteаналогичен итерации по набору, запуску каждого теста по отдельности.Если tests задано, оно должно быть итерируемым объектом отдельных тестовых случаев или других тестовых наборов, которые будут использоваться для построения набора изначально. Дополнительные методы предоставлены для добавления тестовых случаев и наборов в коллекцию позже.
Объекты
TestSuiteведут себя очень похоже на объектыTestCase, за исключением того, что они фактически не реализуют тест. Вместо этого они используются для агрегации тестов в группы тестов, которые должны выполняться вместе. Некоторые дополнительные методы доступны для добавления тестов в экземплярыTestSuite:-
addTests(tests) -
Добавить все тесты из итерируемого объекта экземпляров
TestCaseиTestSuiteв этот набор тестов.Это эквивалентно итерации по tests, вызову
addTest()для каждого элемента.
У
TestSuiteесть следующие методы, общие сTestCase:-
run(result) -
Запустить тесты, связанные с этим набором, собрав результат в объект результатов, переданный как result. Обратите внимание, что в отличие от
TestCase.run(),TestSuite.run()требует передачи объекта результата.
-
debug() -
Запустить тесты, связанные с этим набором, не собирая результат. Это позволяет исключениям, поднятым тестом, передаваться вызывающему методу и может использоваться для поддержки запуска тестов под отладчиком.
-
countTestCases() -
Возвращает количество тестов, представленных этим тестовым объектом, включая все отдельные тесты и поднаборы.
-
__iter__() -
Тесты, сгруппированные с помощью
TestSuite, всегда доступны через итерацию. Подклассы могут лениво предоставлять тесты, переопределяя__iter__(). Обратите внимание, что этот метод может вызываться несколько раз для одного набора (например, при подсчете тестов или сравнении на равенство), поэтому тесты, возвращаемые повторными итерациями доTestSuite.run(), должны быть одинаковыми для каждой итерации вызова. ПослеTestSuite.run()вызывающие методы не должны полагаться на тесты, возвращаемые этим методом, если вызывающий метод не использует подкласс, который переопределяетTestSuite._removeTestAtIndex()для сохранения ссылок на тесты.Изменено в версии 3.2: В предыдущих версиях
TestSuiteнапрямую обращался к тестам, а не через итерацию, поэтому переопределение__iter__()не было достаточно для предоставления тестов.Изменено в версии 3.4: В предыдущих версиях
TestSuiteхранил ссылки на каждыйTestCaseпослеTestSuite.run(). Подклассы могут восстановить это поведение, переопределивTestSuite._removeTestAtIndex().
В типичном использовании объекта
TestSuiteметодrun()вызываетсяTestRunner, а не пользователем, использующим фреймворк тестов. -
Загрузка и выполнение тестов
-
class unittest.TestLoader -
Класс
TestLoaderиспользуется для создания наборов тестов из классов и модулей. Обычно нет необходимости создавать экземпляр этого класса; модульunittestпредоставляет экземпляр, который можно использовать совместно какunittest.defaultTestLoader. Однако использование подкласса или экземпляра позволяет настроить некоторые конфигурируемые свойства.Объекты
TestLoaderимеют следующие атрибуты:-
errors -
Список некритических ошибок, возникших во время загрузки тестов. Не сбрасывается загрузчиком ни в какой момент. Критические ошибки сигнализируются соответствующим методом, который поднимает исключение вызывающему объекту. Некритические ошибки также указываются синтетическим тестом, который при запуске поднимет исходную ошибку.
Введено в версии 3.5.
Объекты
TestLoaderимеют следующие методы:-
loadTestsFromTestCase(testCaseClass) -
Возвращает набор всех тестовых случаев, содержащихся в производном от
TestCasetestCaseClass.Экземпляр тестового случая создается для каждого метода, имя которого указано в
getTestCaseNames(). По умолчанию это имена методов, начинающиеся сtest. ЕслиgetTestCaseNames()не возвращает ни одного метода, но реализован методrunTest(), вместо этого создается единственный тестовый случай для этого метода.
-
loadTestsFromModule(module, pattern=None) -
Возвращает набор всех тестовых случаев, содержащихся в заданном модуле. Этот метод ищет в модуле классы, производные от
TestCase, и создает экземпляр класса для каждого тестового метода, определенного для класса.Примечание
Хотя использование иерархии классов, производных от
TestCase, может быть удобным для совместного использования фикстур и вспомогательных функций, определение тестовых методов в базовых классах, которые не предполагается непосредственно использовать, не работает с этим методом. Однако это может быть полезно, когда фикстуры отличаются и определены в подклассах.Если модуль предоставляет функцию
load_tests, она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это протокол load_tests. Аргумент шаблон передается в качестве третьего аргумента вload_tests.Изменено в версии 3.2: Добавлена поддержка
load_tests.Изменено в версии 3.5: Недокументированный и неофициальный аргумент по умолчанию use_load_tests устарел и игнорируется, хотя он по-прежнему принимается для обратной совместимости. Метод также теперь принимает аргумент только с ключевыми словами шаблон, который передается в
load_testsкак третий аргумент.
-
loadTestsFromName(name, module=None) -
Возвращает набор всех тестовых случаев, заданных строковым спецификатором.
Спецификатор имя представляет собой «точку с запятой», которая может ссылаться на модуль, класс тестового случая, тестовый метод внутри класса тестового случая, экземпляр
TestSuiteили вызываемый объект, который возвращает экземплярTestCaseилиTestSuite.Например, если у вас есть модуль
SampleTestsсодержащий производный отTestCaseклассSampleTestCaseс тремя тестовыми методами (test_one(),test_two(), иtest_three()), спецификатор'SampleTests.SampleTestCase'приведет к тому, что этот метод вернет набор, который запустит все три тестовых метода. Использование спецификатора'SampleTests.SampleTestCase.test_two'приведет к возвращению набора тестов, который запустит только тестовый методtest_two().Метод может по желанию разрешать имя относительно данного модуля.
Изменено в версии 3.5: Если во время обхода имя возникает
ImportErrorилиAttributeError, то будет возвращен синтетический тест, который при запуске поднимет эту ошибку. Эти ошибки включаются в накопленные ошибки self.errors.
-
loadTestsFromNames(names, module=None) -
Аналогично
loadTestsFromName(), но принимает последовательность имен вместо одного имени. Возвращаемое значение — набор тестов, поддерживающий все тесты, определенные для каждого имени.
-
getTestCaseNames(testCaseClass) -
Возвращает отсортированную последовательность имен методов, найденных в testCaseClass; это должен быть подкласс
TestCase.
-
discover(start_dir, pattern='test*.py', top_level_dir=None) -
Найдите все тестовые модули, рекурсивно пройдя по подкаталогам из указанной начальной директории, и верните объект TestSuite, содержащий их. Будут загружены только те тестовые файлы, которые соответствуют шаблону. (Используется синтаксис шаблонов в стиле оболочки.) Будут загружены только имена модулей, которые могут быть импортированы (т.е. являются допустимыми идентификаторами Python).
Все тестовые модули должны быть импортируемы с верхнего уровня проекта. Если начальная директория не является директорией верхнего уровня, то директория верхнего уровня должна быть указана отдельно.
Если импорт модуля завершается ошибкой, например, из-за синтаксической ошибки, то это будет записано как одна ошибка, и поиск продолжит выполняться. Если ошибка импорта вызвана поднятием
SkipTest, она будет записана как пропуск, а не ошибка.Если найден пакет (каталог, содержащий файл, имя которого
__init__.py), пакет будет проверен на наличие функцииload_tests. Если она существует, то она будет вызванаpackage.load_tests(loader, tests, pattern). Поиск тестов позаботится о том, чтобы пакет проверялся на наличие тестов только один раз во время вызова, даже если функция load_tests сама вызываетloader.discover.Если
load_testsсуществует, то поиск не рекурсивно входит в пакет,load_testsотвечает за загрузку всех тестов в пакете.Шаблон намеренно не хранится в качестве атрибута загрузчика, чтобы пакеты могли продолжить поиск сами. top_level_dir хранится, чтобы
load_testsне нужно было передавать этот аргумент вloader.discover().start_dir может быть именем модуля с точкой, а также каталогом.
Введено в версии 3.2.
Изменено в версии 3.4: Модули, которые поднимают
SkipTestпри импорте, регистрируются как пропуски, а не ошибки.Изменено в версии 3.4: start_dir может быть пространством имен пакетов.
Изменено в версии 3.4: Пути сортируются перед импортом, чтобы порядок выполнения был одинаковым, даже если порядок в файловой системе не зависит от имени файла.
Изменено в версии 3.5: Найденные пакеты теперь проверяются на наличие
load_testsнезависимо от того, соответствует ли их путь шаблону, потому что невозможно, чтобы имя пакета соответствовало шаблону по умолчанию.
Следующие атрибуты
TestLoaderможно настроить, используя наследование или присвоение экземпляру:-
testMethodPrefix -
Строка, задающая префикс имен методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию —
'test'.Это влияет на
getTestCaseNames()и все методыloadTestsFrom*().
-
sortTestMethodsUsing -
Функция, используемая для сравнения имен методов при сортировке в
getTestCaseNames()и во всех методахloadTestsFrom*().
-
-
suiteClass -
Вызываемый объект, который строит набор тестов из списка тестов. Методы на результирующем объекте не требуются. Значение по умолчанию — класс
TestSuite.Это влияет на все методы
loadTestsFrom*().
-
testNamePatterns -
Список шаблонов имён тестов в стиле оболочки Unix, которым должны соответствовать методы тестов, чтобы быть включёнными в наборы тестов (см. опцию
-k).Если этот атрибут не
None(значение по умолчанию), все методы тестов, которые должны быть включены в наборы тестов, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что соответствие всегда выполняется с помощьюfnmatch.fnmatchcase(), поэтому, в отличие от шаблонов, переданных в опцию-k, простые шаблоны подстрок должны быть преобразованы с использованием*шаблонов.Это влияет на все методы
loadTestsFrom*().New in version 3.7.
-
-
class unittest.TestResult -
Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие потерпели неудачу.
Объект
TestResultхранит результаты набора тестов. КлассыTestCaseиTestSuiteгарантируют, что результаты записываются должным образом; авторам тестов не нужно беспокоиться о регистрации результата тестов.Фреймворки для тестирования, построенные на основе
unittest, могут потребовать доступ к объектуTestResult, сгенерированному в результате выполнения набора тестов, для целей отчётности; экземплярTestResultвозвращается методомTestRunner.run()для этой цели.Экземпляры
TestResultимеют следующие атрибуты, которые будут интересны при инспектировании результатов выполнения набора тестов:-
errors -
Список, содержащий 2-кортежи из экземпляров
TestCaseи строк, содержащих отформатированные трассировки стека. Каждая пара представляет тест, вызвавший непредвиденную ошибку.
-
failures -
Список, содержащий 2-кортежи из экземпляров
TestCaseи строк, содержащих отформатированные трассировки стека. Каждая пара представляет тест, в котором явным образом было указано о неудаче с использованием методовTestCase.assert*().
-
skipped -
Список, содержащий 2-кортежи из экземпляров
TestCaseи строк, содержащих причину пропуска теста.Добавлена в версии 3.1.
-
expectedFailures -
Список, содержащий 2-кортежи из экземпляров
TestCaseи строк, содержащих отформатированные трассировки стека. Каждая пара представляет ожидаемую неудачу или ошибку тестового случая.
-
unexpectedSuccesses -
Список, содержащий экземпляры
TestCase, которые были помечены как ожидаемые ошибки, но прошли успешно.
-
shouldStop -
Устанавливается в
True, когда выполнение тестов должно быть остановлено методомstop().
-
testsRun -
Общее количество запущенных тестов.
-
buffer -
Если установлено в значение true,
sys.stdoutиsys.stderrбудут буферизованы между вызовамиstartTest()иstopTest(). Собраный вывод будет отображён на консольsys.stdoutиsys.stderrтолько в случае неудачи или ошибки теста. Любой вывод также будет добавлен к сообщению об ошибке/неудаче.Добавлена в версии 3.2.
-
failfast -
Если установлено в значение true, метод
stop()будет вызван при первой ошибке или неудаче, прерывая выполнение теста.Добавлена в версии 3.2.
-
tb_locals -
Если установлено в значение true, локальные переменные будут показаны в трассировках стека.
Добавлена в версии 3.5.
-
wasSuccessful() -
Возвращает
True, если все запущенные тесты прошли успешно, иначе возвращаетFalse.Изменено в версии 3.4: Возвращает
False, если были какие-либоunexpectedSuccessesот тестов, помеченных декораторомexpectedFailure().
-
stop() -
Этот метод можно вызвать, чтобы сигнализировать о том, что набор выполняемых тестов должен быть прерван, установив атрибут
shouldStopв значениеTrue. ОбъектыTestRunnerдолжны учитывать этот флаг и возвращаться без выполнения дополнительных тестов.Например, эта функция используется классом
TextTestRunnerдля остановки фреймворка тестов, когда пользователь подаёт сигнал прерывания с клавиатуры. Интерактивные инструменты, предоставляющие реализацииTestRunner, могут использовать это аналогичным образом.
Следующие методы класса
TestResultиспользуются для поддержания внутренних структур данных и могут быть расширены в подклассах для поддержки дополнительных требований к отчётности. Это особенно полезно при создании инструментов, поддерживающих интерактивную отчётность во время выполнения тестов.-
startTest(test) -
Вызывается, когда тестовый случай test готов к запуску.
-
stopTest(test) -
Вызывается после выполнения тестового случая test, независимо от результата.
-
startTestRun() -
Вызывается один раз перед выполнением любых тестов.
Добавлена в версии 3.1.
-
stopTestRun() -
Вызывается один раз после выполнения всех тестов.
Добавлена в версии 3.1.
-
addError(test, err) -
Вызывается, когда тестовый случай test вызывает непредвиденную ошибку. err — кортеж, возвращаемый
sys.exc_info():(type, value, traceback).Стандартная реализация добавляет кортеж
(test, formatted_err)в атрибутerrorsэкземпляра, где formatted_err — отформатированная трассировка стека, полученная из err.
-
addFailure(test, err) -
Вызывается, когда тестовый случай test сигнализирует о неудаче. err — кортеж, возвращаемый
sys.exc_info():(type, value, traceback).Стандартная реализация добавляет кортеж
(test, formatted_err)в атрибутfailuresэкземпляра, где formatted_err — отформатированная трассировка стека, полученная из err.
-
addSuccess(test) -
Вызывается, когда тестовый случай test проходит успешно.
Стандартная реализация ничего не делает.
-
addSkip(test, reason) -
Вызывается, когда тестовый случай test пропущен. reason — причина пропуска теста.
Стандартная реализация добавляет кортеж
(test, reason)в атрибутskippedэкземпляра.
-
addExpectedFailure(test, err) -
Вызывается, когда тестовый случай test потерпел неудачу или произошла ошибка, но был помечен декоратором
expectedFailure().Стандартная реализация добавляет кортеж
(test, formatted_err)в атрибутexpectedFailuresэкземпляра, где formatted_err — отформатированная трассировка стека, полученная из err.
-
addUnexpectedSuccess(test) -
Вызывается, когда тестовый случай test был помечен декоратором
expectedFailure(), но успешно завершился.Стандартная реализация добавляет тест в атрибут
unexpectedSuccessesэкземпляра.
-
-
addSubTest(test, subtest, outcome) -
Вызывается при завершении подтеста. test — это тестовый случай, соответствующий методу теста. subtest — экземпляр пользовательского
TestCase, описывающий подтест.Если outcome равен
None, подтест выполнен успешно. В противном случае он завершился сбоем с исключением, где outcome — кортеж, возвращаемый функциейsys.exc_info():(type, value, traceback).По умолчанию реализация ничего не делает при успешном завершении и регистрирует сбои подтестов как обычные сбои.
Добавлено в версии 3.4.
-
-
class unittest.TextTestResult(stream, descriptions, verbosity) -
Конкретная реализация
TestResult, используемаяTextTestRunner.Добавлено в версии 3.2: Этот класс ранее назывался
_TextTestResult. Старое имя по-прежнему существует в качестве псевдонима, но устарело.
-
unittest.defaultTestLoader -
Экземпляр класса
TestLoader, предназначенный для совместного использования. Если нет необходимости в настройкеTestLoader, этот экземпляр можно использовать вместо многократного создания новых экземпляров.
-
class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False) -
Базовая реализация исполнителя тестов, выводящая результаты на поток. Если stream имеет значение
None, то по умолчанию используетсяsys.stderrв качестве потока вывода. Этот класс имеет несколько настраиваемых параметров, но по сути очень прост. Графические приложения, выполняющие наборы тестов, должны предоставить альтернативные реализации. Такие реализации должны принимать**kwargsв качестве интерфейса, так как конструкция исполнителей изменяется при добавлении функций в unittest.По умолчанию этот исполнитель отображает
DeprecationWarning,PendingDeprecationWarning,ResourceWarningиImportWarningдаже если они по умолчанию игнорируются. Предупреждения об устаревании, вызванные устаревшими методами unittest, также обрабатываются особым образом, и при фильтрации предупреждений, равной'default'или'always', они будут отображаться только один раз на модуль, чтобы избежать слишком большого количества сообщений об ошибках. Это поведение можно переопределить, используя параметры Python-Wdили-Wa(см. Управление предупреждениями), оставив warnings равнымNone.Изменено в версии 3.2: Добавлен аргумент
warnings.Изменено в версии 3.2: По умолчанию поток устанавливается в
sys.stderrво время инициализации, а не во время импорта.Изменено в версии 3.5: Добавлен параметр tb_locals.
-
_makeResult() -
Этот метод возвращает экземпляр
TestResult, используемыйrun(). Он не предназначен для прямого вызова, но может быть переопределён в подклассах для предоставления настраиваемогоTestResult._makeResult()создаёт экземпляр класса или вызываемого объекта, переданного в конструкторTextTestRunnerв качестве аргументаresultclassпо умолчанию. По умолчанию он равенTextTestResult, еслиresultclassне предоставлен. Класс результата инициализируется следующими аргументами:stream, descriptions, verbosity
-
run(test) -
Этот метод — основной публичный интерфейс
TextTestRunner. Этот метод принимает экземплярTestSuiteилиTestCase.TestResultсоздаётся путём вызова_makeResult(), и тесты выполняются, а результаты выводятся в stdout.
-
-
unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None) -
Программа командной строки, загружающая набор тестов из module и выполняющая их; в основном для удобного запуска тестовых модулей. Самый простой способ использования этой функции — включить следующую строку в конце тестового сценария:
if __name__ == '__main__': unittest.main()Вы можете запустить тесты с более подробной информацией, передав аргумент verbosity:
if __name__ == '__main__': unittest.main(verbosity=2)Аргумент defaultTest — это имя одного теста или итерируемый объект имён тестов для запуска, если имена тестов не указаны через argv. Если не указано или
Noneи имена тестов не предоставлены через argv, выполняются все тесты, найденные в module.Аргумент argv может представлять собой список опций, передаваемых программе, при этом первый элемент — это имя программы. Если не указано или
None, используются значенияsys.argv.Аргумент testRunner может быть классом исполнителя тестов или уже созданным экземпляром. По умолчанию
mainвызываетsys.exit()с кодом завершения, указывающим на успех или неудачу выполненных тестов.Аргумент testLoader должен быть экземпляром
TestLoaderи по умолчанию равенdefaultTestLoader.mainподдерживает использование из интерактивного интерпретатора, передавая аргументexit=False. Это отображает результат на стандартном выводе без вызоваsys.exit():>>> from unittest import main >>> main(module='test_module', exit=False)
Параметры failfast, catchbreak и buffer имеют тот же эффект, что и одноимённые параметры параметров командной строки.
Аргумент warnings указывает фильтр предупреждений, который должен использоваться при выполнении тестов. Если он не указан, он останется
Noneесли опция-Wпередана в python (см. Управление предупреждениями), иначе он будет установлен в'default'.Вызов
mainфактически возвращает экземпляр классаTestProgram. Это хранит результат выполненных тестов как атрибутresult.Изменено в версии 3.1: Добавлен параметр exit.
Изменено в версии 3.2: Добавлены параметры verbosity, failfast, catchbreak, buffer и warnings.
Изменено в версии 3.4: Параметр defaultTest был изменён для поддержки итерируемых объектов имён тестов.
Протокол load_tests
Введено в версии 3.2.
Модули или пакеты могут настраивать, как тесты загружаются из них во время обычных запусков тестов или обнаружения тестов, реализовав функцию с именем load_tests.
Если модуль теста определяет load_tests, он будет вызван TestLoader.loadTestsFromModule() со следующими аргументами:
load_tests(loader, standard_tests, pattern)
где pattern передается непосредственно из loadTestsFromModule. По умолчанию он равен None.
Функция должна возвращать TestSuite.
loader — это экземпляр TestLoader, выполняющий загрузку. standard_tests — это тесты, которые загружались бы по умолчанию из модуля. Для модулей тестов обычно достаточно добавить или удалить тесты из стандартного набора тестов. Третий аргумент используется при загрузке пакетов в рамках обнаружения тестов.
Типичная функция load_tests, загружающая тесты из определенного набора классов TestCase, может выглядеть так:
test_cases = (TestCase1, TestCase2, TestCase3)
def load_tests(loader, tests, pattern):
suite = TestSuite()
for test_class in test_cases:
tests = loader.loadTestsFromTestCase(test_class)
suite.addTests(tests)
return suite
Если обнаружение запускается в каталоге, содержащем пакет, либо из командной строки, либо вызывая TestLoader.discover(), то пакет __init__.py будет проверен на наличие load_tests. Если эта функция не существует, обнаружение будет рекурсивно переходить в пакет, как будто это просто другой каталог. В противном случае, обнаружение тестов пакета будет оставлено load_tests, который вызывается со следующими аргументами:
load_tests(loader, standard_tests, pattern)
Это должно вернуть TestSuite, представляющий все тесты из пакета. (standard_tests будет содержать только тесты, собранные из __init__.py.)
Поскольку шаблон передается в load_tests, пакет свободен продолжать (и потенциально изменять) обнаружение тестов. Функция «ничего не делать» load_tests для тестового пакета будет выглядеть так:
def load_tests(loader, standard_tests, pattern):
# top level directory cached on loader instance
this_dir = os.path.dirname(__file__)
package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
standard_tests.addTests(package_tests)
return standard_tests
Изменено в версии 3.5: Обнаружение больше не проверяет имена пакетов на соответствие pattern из-за невозможности совпадения имен пакетов с шаблоном по умолчанию.
Фикстуры классов и модулей
Фикстуры на уровне класса и модуля реализованы в TestSuite. Когда тестовый набор встречает тест из нового класса, tearDownClass() предыдущего класса (если он есть) вызывается, за которым следует setUpClass() нового класса.
Аналогично, если тест из другого модуля, чем предыдущий тест, то tearDownModule предыдущего модуля выполняется, за которым следует setUpModule нового модуля.
После выполнения всех тестов выполняются заключительные tearDownClass и tearDownModule.
Обратите внимание, что общие фикстуры плохо взаимодействуют с [возможными] функциями, такими как распараллеливание тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.
По умолчанию тесты, созданные загрузчиками тестов unittest, группируются вместе по модулям и классам. Это приведет к тому, что setUpClass / setUpModule (и т. д.) будут вызваны ровно один раз на класс и модуль. Если вы рандомизируете порядок, так что тесты из разных модулей и классов расположены рядом друг с другом, то эти общие функции фикстуры могут вызываться несколько раз в одном запуске тестов.
Общие фикстуры не предназначены для работы с наборами с нестандартным порядком. Для фреймворков, не желающих поддерживать общие фикстуры, все еще существует BaseTestSuite.
Если при выполнении одной из общих функций фикстуры возникает исключение, тест регистрируется как ошибка. Поскольку нет соответствующего экземпляра теста, создается объект _ErrorHolder (который имеет тот же интерфейс, что и TestCase) для представления ошибки. Если вы просто используете стандартный исполняемый файл тестов unittest, эта деталь не имеет значения, но если вы автор фреймворка, она может быть важна.
setUpClass и tearDownClass
Эти методы должны быть реализованы как методы класса:
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()
Если вам нужны setUpClass и tearDownClass для базовых классов, то вы должны вызвать их сами. Реализации в TestCase пустые.
Если во время setUpClass возникает исключение, тесты в классе не выполняются, и tearDownClass не выполняется. Для пропущенных классов setUpClass и tearDownClass не будут выполняться. Если исключение является исключением SkipTest, то класс будет зарегистрирован как пропущенный, а не как ошибка.
setUpModule и tearDownModule
Эти методы должны быть реализованы как функции:
def setUpModule():
createConnection()
def tearDownModule():
closeConnection()
Если в setUpModule возникает исключение, то тесты в модуле не выполняются, и tearDownModule не выполняется. Если исключение является исключением SkipTest, то модуль будет зарегистрирован как пропущенный, а не как ошибка.
Чтобы добавить код очистки, который должен выполняться даже в случае исключения, используйте addModuleCleanup:
-
unittest.addModuleCleanup(function, /, *args, **kwargs) -
Добавляет функцию, которая будет вызываться после
tearDownModule()для очистки ресурсов, используемых во время класса теста. Функции будут вызываться в обратном порядке к порядку их добавления (LIFO). Они вызываются с любыми аргументами и ключевыми аргументами, переданными вaddModuleCleanup()при их добавлении.Если
setUpModule()завершается неудачно, что означает, чтоtearDownModule()не вызывается, то любые добавленные функции очистки все равно будут вызваны.Введено в версии 3.8.
-
unittest.doModuleCleanups() -
Эта функция вызывается безусловно после
tearDownModule(), или послеsetUpModule()еслиsetUpModule()вызывает исключение.Она отвечает за вызов всех функций очистки, добавленных
addModuleCleanup(). Если вам нужны функции очистки, чтобы вызываться *до*tearDownModule(), то вы можете сами вызватьdoModuleCleanups().doModuleCleanups()извлекает методы из стека функций очистки по одному за раз, поэтому ее можно вызывать в любое время.Введено в версии 3.8.
Обработка сигналов
Новая версия 3.2.
Командная строка опция -c/--catch для unittest, а также параметр catchbreak к unittest.main(), обеспечивают более удобную обработку нажатия Ctrl+C во время выполнения теста. При включенном поведении перехвата прерывания, нажатие Ctrl+C позволит текущему выполняемому тесту завершиться, а затем выполнение теста закончится и будут отображены все результаты до этого момента. Второе нажатие Ctrl+C сгенерирует KeyboardInterrupt стандартным способом.
Обработчик сигнала для обработки Ctrl+C пытается сохранить совместимость с кодом или тестами, которые устанавливают собственный обработчик signal.SIGINT. Если обработчик unittest вызывается, но не является установленным обработчиком signal.SIGINT, т.е. он был заменён тестируемой системой и делегирован, то вызывается обработчик по умолчанию. Это обычно ожидаемое поведение кода, который заменяет установленный обработчик и делегирует ему. Для отдельных тестов, которым требуется unittest отключение обработки нажатия Ctrl+C, можно использовать декоратор removeHandler().
Для авторов фреймворков существуют несколько служебных функций, позволяющих включить функциональность обработки Ctrl+C в фреймворках для тестов.
-
unittest.installHandler() -
Установить обработчик Ctrl+C. При получении
signal.SIGINT(обычно в ответ на нажатие пользователем Ctrl+C) для всех зарегистрированных результатов вызываетсяstop().
-
unittest.registerResult(result) -
Зарегистрировать объект
TestResultдля обработки нажатия Ctrl+C. Регистрация результата сохраняет слабую ссылку на него, поэтому она не препятствует сборке мусора для результата.Регистрация объекта
TestResultне имеет побочных эффектов, если обработка нажатия Ctrl+C не включена, поэтому фреймворки для тестов могут безусловно регистрировать все созданные результаты независимо от того, включена ли обработка.
-
unittest.removeResult(result) -
Удалить зарегистрированный результат. После удаления результата
stop()больше не будет вызываться для этого объекта результата в ответ на нажатие Ctrl+C.
-
unittest.removeHandler(function=None) -
При вызове без аргументов эта функция удаляет обработчик Ctrl+C, если он был установлен. Эту функцию также можно использовать в качестве декоратора теста, чтобы временно удалить обработчик во время выполнения теста:
@unittest.removeHandler def test_signal_handling(self): ...
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/unittest.html