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.
Если у вас установлен пакет глобально, и вы пытаетесь выполнить обнаружение тестов на другой копии пакета, то импорт может произойти из неправильного места. Если это произойдёт, обнаружение тестов выдаст предупреждение и завершится.
Если вы передаёте каталог запуска как имя пакета, а не путь к каталогу, то обнаружение предполагает, что независимо от того, откуда оно импортируется, это то место, которое вы имели в виду, поэтому предупреждение не будет выдано.
Тестовые модули и пакеты могут настроить загрузку и обнаружение тестов с помощью протокола load_tests.
Изменено в версии 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предоставляет несколько методов проверки для обнаружения и отчётности об ошибках. В следующей таблице перечислены наиболее часто используемые методы (см. таблицы ниже для получения дополнительных assert методов):Метод
Проверяет, что
Введено в
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
Все методы assert принимают аргумент 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
-
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.
-
Существуют и другие методы, используемые для выполнения более конкретных проверок, например:
Метод
Проверяет, что
Новое в
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(), для проверки, сравниваются ли два объекта одного и того же типа (не подклассы) на равенство. 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) -
Возвращает набор всех тестовых случаев, содержащихся в
testCaseClass, производных отTestCase.Экземпляр тестового случая создается для каждого метода, имя которого указано в
getTestCaseNames(). По умолчанию это имена методов, начинающиеся сtest. ЕслиgetTestCaseNames()не возвращает никаких методов, но реализован методrunTest(), вместо этого создается один тестовый случай для этого метода.
-
loadTestsFromModule(module, pattern=None) -
Возвращает набор всех тестовых случаев, содержащихся в указанном модуле. Этот метод ищет в модуле классы, производные от
TestCase, и создает экземпляр класса для каждого тестового метода, определенного для класса.Примечание
Хотя использование иерархии классов, производных от
TestCase, удобно для совместного использования фикстур и вспомогательных функций, определение тестовых методов в базовых классах, которые не предназначены для непосредственного создания экземпляров, не работает с этим методом. Однако это может быть полезно, когда фикстуры отличаются и определены в подклассах.Если модуль предоставляет функцию
load_tests, она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это протокол load_tests. Аргумент pattern передаётся как третий аргумент вload_tests.Изменено в версии 3.2: Добавлена поддержка
load_tests.Изменено в версии 3.5: Недокументированный и неофициальный необязательный аргумент use_load_tests устарел и игнорируется, хотя он всё ещё принимается для обратной совместимости. Метод также теперь принимает ключевой аргумент pattern, который передается в
load_testsкак третий аргумент.
-
loadTestsFromName(name, module=None) -
Возвращает набор всех тестовых случаев, заданных строковым спецификатором.
Спецификатор name — это «точечное имя», которое может разрешиться либо в модуль, либо в класс тестового случая, либо в тестовый метод внутри класса тестового случая, либо в экземпляр
TestSuite, либо в вызываемый объект, который возвращает экземплярTestCaseилиTestSuite. Эти проверки применяются в указанном порядке; то есть, метод в возможном классе тестового случая будет выбран как «метод теста внутри класса тестового случая», а не как «вызываемый объект».Например, если у вас есть модуль
SampleTests, содержащий класс, производный отTestCase,SampleTestCase, с тремя тестовыми методами (test_one(),test_two(), иtest_three()), спецификатор'SampleTests.SampleTestCase'заставит этот метод вернуть набор, который выполнит все три тестовых метода. Используя спецификатор'SampleTests.SampleTestCase.test_two'вы получите набор тестов, который выполнит только метод тестаtest_two().Спецификатор может ссылаться на модули и пакеты, которые не были импортированы; они будут импортированы как побочный эффект.
Метод необязательно разрешает name относительно данного модуля.
Изменено в версии 3.5: Если при прохождении по name возникает
ImportErrorилиAttributeError, то возвращается синтетический тест, который поднимает эту ошибку при выполнении. Эти ошибки включаются в ошибки, накопленные self.errors.
-
loadTestsFromNames(names, module=None) -
Аналогично
loadTestsFromName(), но принимает последовательность имён, а не одно имя. Возвращаемое значение — набор тестов, которые поддерживают все тесты, определённые для каждого имени.
-
getTestCaseNames(testCaseClass) -
Возвращает отсортированный список имён методов, найденных внутри testCaseClass; это должен быть подкласс
TestCase.
-
discover(start_dir, pattern='test*.py', top_level_dir=None) -
Находит все тестовые модули, рекурсивно перебирая подкаталоги из указанной начальной директории и возвращает объект TestSuite, содержащий их. Будут загружены только тестовые файлы, соответствующие шаблону pattern. (Используется синтаксис шаблонов оболочки.) Будут загружены только те имена модулей, которые являются импортируемыми (т. е. являются допустимыми идентификаторами 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независимо от того, соответствует ли их путь шаблону pattern, потому что имя пакета не может соответствовать шаблону по умолчанию.
Следующие атрибуты
TestLoaderможно настроить, либо создав подкласс, либо изменив значение у экземпляра:-
testMethodPrefix -
Строка, задающая префикс имён методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию —
'test'.Это влияет на
getTestCaseNames()и все методыloadTestsFrom*().
-
sortTestMethodsUsing -
Функция, используемая для сравнения имён методов при их сортировке в
getTestCaseNames()и всех методахloadTestsFrom*().
-
-
suiteClass -
Объект вызываемого типа, который создаёт набор тестов из списка тестов. Методы полученного объекта не нужны. Значение по умолчанию — класс
TestSuite.Это влияет на все методы
loadTestsFrom*().
-
testNamePatterns -
Список шаблонов имён тестов в стиле командной строки Unix, которым должны соответствовать методы тестов, чтобы их включить в наборы тестов (см. опцию
-v).Если этот атрибут не
None(по умолчанию), все методы тестов, которые нужно включить в наборы тестов, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что сопоставления всегда выполняются с помощьюfnmatch.fnmatchcase(), поэтому в отличие от шаблонов, переданных в опцию-v, простые шаблоны подстрок должны быть преобразованы с использованием символов подстановки*.Это влияет на все методы
loadTestsFrom*().Новое в версии 3.7.
-
-
class unittest.TestResult -
Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие потерпели неудачу.
Объект
TestResultхранит результаты набора тестов. КлассыTestCaseиTestSuiteгарантируют, что результаты записываются корректно; авторам тестов не нужно беспокоиться о записи результатов тестов.Фреймворки тестирования, построенные на основе
unittest, могут потребовать доступа к объектуTestResult, сгенерированному при запуске набора тестов, для целей отчётности; экземплярTestResultвозвращается методомTestRunner.run()для этой цели.Экземпляры
TestResultобладают следующими атрибутами, которые будут интересны при инспектировании результатов запуска набора тестов:-
errors -
Список, содержащий пары (экземпляр
TestCase, строка с отформатированными трейсами обращений к стеку вызовов). Каждая пара представляет тест, в котором возникло непредвиденное исключение.
-
failures -
Список, содержащий пары (экземпляр
TestCase, строка с отформатированными трейсами обращений к стеку вызовов). Каждая пара представляет тест, в котором явно было указано о сбое с использованием методовTestCase.assert*().
-
skipped -
Список, содержащий пары (экземпляр
TestCase, строка с причиной пропуска теста).Новая функция в версии 3.1.
-
expectedFailures -
Список, содержащий пары (экземпляр
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(), и тесты запускаются, а результаты выводятся в стандартный вывод.
-
-
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)
где шаблон передаётся напрямую из 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: Обнаружение больше не проверяет имена пакетов на соответствие шаблону из-за невозможности соответствия имён пакетов по умолчанию.
Фикстуры классов и модулей
Фикстуры уровня класса и модуля реализованы в 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()вызывает исключение.Она отвечает за вызов всех функций очистки, добавленных с помощью
addCleanupModule(). Если вам нужны функции очистки, которые должны быть вызваны до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, т.е. он был заменен тестируемой системой и делегирован, то он вызывает стандартный обработчик. Это обычно ожидаемое поведение кода, который заменяет установленный обработчик и делегирует ему. Для отдельных тестов, которым требуется отключить обработку нажатия 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–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/library/unittest.html