Содержание страницы
unittest – фреймворк для модульного тестирования¶unittest – Unit testing framework
Исходный код: Lib/unittest/__init__.py
(Если вы уже знакомы с основными понятиями тестирования, можете перейти к списку методов assert.)
Фреймворк модульного тестирования unittest изначально был вдохновлён JUnit и имеет схожий подход с основными фреймворками модульного тестирования на других языках. Он поддерживает автоматизацию тестов, совместное использование кода подготовки и завершения тестов, объединение тестов в коллекции и независимость тестов от системы отчётов.
Для этого unittest поддерживает несколько важных концепций в объектно-ориентированном стиле:
- тестовая фикстура
Тестовая фикстура представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, а также все связанные действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск серверного процесса.
- тестовый случай
Тестовый случай – это отдельная единица тестирования. Он проверяет определённую реакцию на конкретный набор входных данных.
unittestпредоставляет базовый классTestCase, который можно использовать для создания новых тестовых случаев.- набор тестов
Набор тестов – это совокупность тестовых случаев, наборов тестов или и того, и другого. Он используется для объединения тестов, которые должны выполняться вместе.
- исполнитель тестов
Исполнитель тестов – это компонент, который управляет выполнением тестов и предоставляет результат пользователю. Исполнитель может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение, указывающее на результаты выполнения тестов.
См. также
- Модуль
doctest Ещё один модуль поддержки тестирования с совершенно другим подходом.
- Простое тестирование в Smalltalk: с шаблонами
Оригинальная статья Кента Бека о фреймворках тестирования, в которых используется тот же шаблон, что и в
unittest.- pytest
Сторонний фреймворк модульного тестирования с более лёгким синтаксисом для написания тестов. Например,
assert func(10) == 42.- Таксономия инструментов тестирования Python
Обширный список инструментов тестирования Python, включая фреймворки функционального тестирования и библиотеки имитационных объектов (mock).
- Список рассылки по тестированию в Python
Группа по интересам для обсуждения тестирования и инструментов тестирования в Python.
Скрипт Tools/unittestgui/unittestgui.py в дистрибутиве исходных кодов Python – это графический инструмент для обнаружения и выполнения тестов. Он в значительной степени предназначен для упрощения работы с тестированием для новичков в модульном тестировании. Для производственных сред рекомендуется, чтобы тесты запускались системой непрерывной интеграции, такой как Buildbot, Jenkins, GitHub Actions или AppVeyor.
Простой пример¶Basic example
Модуль 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'])
# проверить, что s.split завершается ошибкой, если разделитель не строка
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.test_isupper) ... ok
test_split (__main__.TestStringMethods.test_split) ... ok
test_upper (__main__.TestStringMethods.test_upper) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
Представленные выше примеры демонстрируют наиболее часто используемые возможности unittest, которых достаточно для многих повседневных задач тестирования. Оставшаяся часть документации рассматривает полный набор функций с самого начала.
Изменено в версии 3.11: Возврат значения из тестового метода (кроме значения по умолчанию None) теперь считается устаревшим.
Интерфейс командной строки¶Command-Line Interface
Модуль 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: В более ранних версиях можно было запускать только отдельные тестовые методы, а не модули или классы.
Параметры командной строки¶Command-line options
unittest поддерживает следующие параметры командной строки:
- -b, --buffer¶
Потоки стандартного вывода и стандартной ошибки буферизируются во время выполнения теста. Вывод при успешном тесте отбрасывается. При ошибке или провале теста вывод выводится обычным образом и добавляется к сообщениям о неудаче.
- -c, --catch¶
Control-C во время выполнения теста ожидает завершения текущего теста, а затем выводит все результаты, полученные на данный момент. Повторное нажатие Control-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.
Командная строка также может использоваться для автоматического обнаружения тестов, для запуска всех тестов в проекте или только их части.
Обнаружение тестов¶Test Discovery
Новое в версии 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.
Если пакет установлен глобально, и предпринимается попытка обнаружения тестов в другой копии пакета, то импорт может произойти из неправильного места. Если это произойдет, обнаружение тестов выдаст предупреждение и завершится.
Если указать начальный каталог как имя пакета, а не путь к каталогу, то discover считает, что местоположение, из которого он импортирует, и есть то, которое вы имели в виду, поэтому предупреждение не появится.
Тестовые модули и пакеты могут настраивать загрузку и обнаружение тестов с помощью протокола load_tests.
Изменено в версии 3.4: Обнаружение тестов поддерживает пакеты пространств имён
для начального каталога. Обратите внимание: нужно указать также каталог верхнего уровня
(например, python -m unittest discover -s root/namespace -t root).
Изменено в версии 3.11: unittest убрана поддержка пакетов пространств имён
в Python 3.11. Она была сломана начиная с Python 3.7. Начальный каталог и
подкаталоги, содержащие тесты, должны быть обычными пакетами, имеющими
__init__.py файл.
Каталоги, содержащие начальный каталог, всё ещё могут быть пакетом пространства имён. В этом случае нужно указать начальный каталог как точечное имя пакета, а целевой каталог – явно. Например:
# proj/ <-- текущая директория
# namespace/
# mypkg/
# __init__.py
# test_mypkg.py
python -m unittest discover -s namespace.mypkg -t .
Организация тестового кода¶Organizing test code
Основными строительными блоками модульного тестирования являются тестовые случаи – отдельные сценарии, которые необходимо настроить и проверить на корректность. В 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 предоставляет для этого механизм:
набор тестов, представленный классом TestSuite из модуля unittest. В большинстве случаев вызов 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, всё равно должны быть в отдельных модулях – так почему бы не придерживаться этого подхода?
Если стратегия тестирования меняется, нет необходимости изменять исходный код.
Повторное использование старого тестового кода¶Re-using old test code
Некоторые пользователи могут иметь существующий тестовый код, который они хотели бы запускать из unittest, не преобразовывая каждую старую тестовую функцию в подкласс TestCase.
По этой причине unittest предоставляет класс FunctionTestCase.
Этот подкласс TestCase можно использовать для обёртывания существующей тестовой функции. Также можно предоставить функции настройки (set-up) и завершения (tear-down).
Рассмотрим следующую тестовую функцию:
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.
Пропуск тестов и ожидаемые сбои¶Skipping tests and expected failures
Новое в версии 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):
# Тесты, которые работают только для определённой версии библиотеки.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# код тестирования для Windows
pass
def test_maybe_skipped(self):
if not external_resource_available():
self.skipTest("external resource not available")
# тестовый код, зависящий от внешнего ресурса
pass
Это вывод приведённого выше примера в подробном режиме:
test_format (__main__.MyTestCase.test_format) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase.test_nothing) ... skipped 'demonstrating skipping'
test_maybe_skipped (__main__.MyTestCase.test_maybe_skipped) ... skipped 'external resource not available'
test_windows_support (__main__.MyTestCase.test_windows_support) ... 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().
Различение итераций теста с помощью подтестов¶Distinguishing test iterations using subtests
Новое в версии 3.4.
Когда между тестами есть очень небольшие различия, например
некоторые параметры, unittest позволяет различать их внутри
тела тестового метода с помощью контекстного менеджера subTest().
Например, следующий тест:
class NumbersTest(unittest.TestCase):
def test_even(self):
"""
Проверить, что все числа от 0 до 5 чётные.
"""
for i in range(0, 6):
with self.subTest(i=i):
self.assertEqual(i % 2, 0)
выдаст следующий результат:
======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=1)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 11, in test_even
self.assertEqual(i % 2, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=3)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 11, in test_even
self.assertEqual(i % 2, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=5)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 11, in test_even
self.assertEqual(i % 2, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0
Без использования подтеста выполнение остановилось бы после первого сбоя,
и ошибку было бы труднее диагностировать, поскольку значение i
не отображалось бы:
======================================================================
FAIL: test_even (__main__.NumbersTest.test_even)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
Классы и функции¶Classes and functions
В этом разделе подробно описывается API unittest.
Тестовые примеры¶Test cases
- 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 для проверки и сообщения об ошибках. В следующей таблице перечислены наиболее часто используемые методы (см. таблицы ниже для получения дополнительных методов 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 относятся к одному и тому же типу и это list, tuple, dict, set, frozenset, str или любой тип, зарегистрированный подклассом с помощью
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
- Блок
withне пишет в журнал logger с минимальным level
3.10
- assertRaises(exception, callable, *args, **kwds)¶
- assertRaises(exception, *, msg=None)
Проверяет, что исключение возбуждается, когда callable вызывается с любыми позиционными или именованными аргументами, которые также передаются в
assertRaises(). Тест проходит, если возбуждается исключение, считается ошибкой, если возбуждается другое исключение, или не проходит, если исключение не возбуждается. Чтобы перехватить любое из группы исключений, можно передать кортеж, содержащий классы исключений, как исключение.Если переданы только аргументы исключение и, возможно, 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)
Проверяет, что предупреждение вызывается, когда вызываемый объект вызывается с любыми позиционными или ключевыми аргументами, которые также передаются в
assertWarns(). Тест проходит, если предупреждение вызывается, и не проходит в противном случае. Любое исключение считается ошибкой. Чтобы перехватить любое из группы предупреждений, можно передать кортеж, содержащий классы предупреждений, в качестве предупреждения.Если указаны только предупреждение и, возможно, msg, возвращается менеджер контекста, позволяющий писать тестируемый код inline, а не в виде функции:
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(), но также проверяет, что регулярное выражение соответствует сообщению вызванного предупреждения. Регулярное выражение может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, пригодное для использования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)¶
Менеджер контекста для проверки того, что хотя бы одно сообщение зарегистрировано в логгере или одном из его потомков, с уровнем не ниже указанного уровня.
Если указан, логгер должен быть объектом
logging.Loggerилиstr, задающим имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения, не заблокированные непропагандирующим дочерним логгером.Если указан, уровень должен быть числовым уровнем логирования или его строковым эквивалентом (например,
"ERROR"илиlogging.ERROR). По умолчаниюlogging.INFO.Тест проходит, если хотя бы одно сообщение, отправленное внутри блока
with, соответствует условиям логгера и уровня, в противном случае тест не проходит.Объект, возвращаемый менеджером контекста, представляет собой вспомогательный объект для записи, который отслеживает соответствующие сообщения журнала. Он имеет два атрибута:
- records¶
Список объектов
logging.LogRecordсоответствующих сообщений журнала.
Пример:
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)¶
Менеджер контекста для проверки того, что на логгере или одном из его потомков не зарегистрировано ни одного сообщения с уровнем не ниже указанного уровня.
Если указан, логгер должен быть объектом
logging.Loggerилиstr, задающим имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения.Если указан, уровень должен быть числовым уровнем логирования или его строковым эквивалентом (например,
"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 приблизительно равны (или не равны), вычисляя разность, округляя до заданного числа десятичных знаков places (по умолчанию 7) и сравнивая с нулём. Обратите внимание, что эти методы округляют значения до заданного числа десятичных знаков (т.е. как функция
round()), а не до значащих цифр.Если указан delta вместо places, то разность между 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. Если они не равны, в сообщение об ошибке включается diff двух строк с подсветкой различий. Этот метод используется по умолчанию при сравнении строк с помощью
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¶
Этот атрибут управляет максимальной длиной вывода различий, выводимых методами утверждения, которые сообщают о различиях при неудаче. По умолчанию – 80*8 символов. Методы утверждения, на которые влияет этот атрибут:
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.
- enterContext(cm)¶
Входит в предоставленный менеджер контекста. В случае успеха также добавляет его метод
__exit__()как функцию очистки с помощьюaddCleanup()и возвращает результат метода__enter__().Новое в версии 3.11.
- doCleanups()¶
Этот метод вызывается безусловно после
tearDown()или послеsetUp(), еслиsetUp()вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных с помощью
addCleanup(). Если необходимо, чтобы функции очистки вызывались доtearDown(), то можно вызватьdoCleanups()самостоятельно.doCleanups()извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любой момент.Новое в версии 3.1.
- classmethod addClassCleanup(function, /, *args, **kwargs)¶
Добавляет функцию, которая будет вызвана после
tearDownClass()для очистки ресурсов, использованных во время тестового класса. Функции вызываются в обратном порядке по сравнению с порядком их добавления (LIFO). Они вызываются с теми аргументами и именованными аргументами, которые были переданы вaddClassCleanup()при их добавлении.Если
setUpClass()завершается ошибкой, то естьtearDownClass()не вызывается, то все добавленные функции очистки всё равно будут вызваны.Новое в версии 3.8.
- classmethod enterClassContext(cm)¶
Входит в предоставленный менеджер контекста. В случае успеха также добавляет его метод
__exit__()как функцию очистки с помощьюaddClassCleanup()и возвращает результат метода__enter__().Новое в версии 3.11.
- 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)¶
Этот метод принимает корутину, которая может использоваться как функция очистки.
- coroutine enterAsyncContext(cm)¶
Входит в предоставленный асинхронный менеджер контекста. В случае успеха также добавляет его метод
__aexit__()как функцию очистки с помощьюaddAsyncCleanup()и возвращает результат метода__aenter__().Новое в версии 3.11.
- 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.
Устаревшие псевдонимы¶Deprecated aliases
По историческим причинам некоторые методы 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().
Группировка тестов¶Grouping tests
- 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, а не через тестовую оболочку конечного пользователя.
Загрузка и запуск тестов¶Loading and running tests
- class unittest.TestLoader¶
Класс
TestLoaderиспользуется для создания тестовых наборов из классов и модулей. Обычно нет необходимости создавать экземпляр этого класса; модульunittestпредоставляет экземпляр, который можно использовать совместно какunittest.defaultTestLoader. Однако использование подкласса или экземпляра позволяет настраивать некоторые конфигурируемые свойства.Объекты
TestLoaderимеют следующие атрибуты:- errors¶
Список нефатальных ошибок, возникших при загрузке тестов. Не сбрасывается загрузчиком ни в какой момент. Фатальные ошибки сигнализируются соответствующим методом, который генерирует исключение для вызывающего кода. Нефатальные ошибки также указываются синтетическим тестом, который при выполнении вызовет исходную ошибку.
Новое в версии 3.5.
Объекты
TestLoaderимеют следующие методы:- loadTestsFromTestCase(testCaseClass)¶
Возвращает набор всех тестов, содержащихся в
testCaseClass, производном отTestCase.Экземпляр тестового случая создаётся для каждого метода, именованного
getTestCaseNames(). По умолчанию это имена методов, начинающиеся сtest. ЕслиgetTestCaseNames()не возвращает ни одного метода, но методrunTest()реализован, то вместо этого создаётся один тестовый случай для этого метода.
- loadTestsFromModule(module, pattern=None)¶
Возвращает набор всех тестовых случаев, содержащихся в данном модуле. Этот метод ищет в module классы, производные от
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, содержащий классSampleTestCase, производный отTestCase, с тремя тестовыми методами (test_one(),test_two()иtest_three()), спецификатор'SampleTests.SampleTestCase'заставит этот метод вернуть набор, который выполнит все три тестовых метода. Использование спецификатора'SampleTests.SampleTestCase.test_two'приведёт к возврату тестового набора, который выполнит только тестовый методtest_two(). Спецификатор может ссылаться на модули и пакеты, которые не были импортированы; они будут импортированы как побочный эффект.Метод опционально разрешает name относительно заданного module.
Изменено в версии 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. (Используется сопоставление с образцом в стиле shell.) Будут загружены только имена модулей, которые можно импортировать (т.е. являются допустимыми идентификаторами 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, поскольку имя пакета не может соответствовать шаблону по умолчанию.Изменено в версии 3.11: start_dir не может быть пакетом пространства имён. Это поведение было нарушено начиная с Python 3.7, и Python 3.11 официально удаляет его.
Следующие атрибуты
TestLoaderможно настроить либо через наследование, либо через присваивание экземпляру:- testMethodPrefix¶
Строка, задающая префикс имён методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию –
'test'.Это влияет на
getTestCaseNames()и все методыloadTestsFrom*.
- sortTestMethodsUsing¶
Функция, используемая для сравнения имён методов при их сортировке в
getTestCaseNames()и во всех методахloadTestsFrom*.
- suiteClass¶
Вызываемый объект, который создаёт тестовый набор из списка тестов. Никакие методы результирующего объекта не требуются. Значение по умолчанию – класс
TestSuite.Это влияет на все методы
loadTestsFrom*.
- testNamePatterns¶
Список шаблонов имён тестов в стиле оболочки Unix (символы подстановки), которым должны соответствовать тестовые методы для включения в наборы тестов (см. опцию
-k).Если этот атрибут не равен
None(по умолчанию), все тестовые методы, которые должны быть включены в тестовые наборы, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что сопоставление всегда выполняется с помощьюfnmatch.fnmatchcase(), поэтому, в отличие от шаблонов, переданных опции-k, простые шаблоны подстрок придётся преобразовать с использованием подстановочных знаков*.Это влияет на все методы
loadTestsFrom*.Добавлено в версии 3.7.
- class unittest.TestResult¶
Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие завершились неудачей.
Объект
TestResultхранит результаты набора тестов. КлассыTestCaseиTestSuiteобеспечивают правильную запись результатов; авторам тестов не нужно беспокоиться о записи результатов тестов.Тестовые фреймворки, построенные на базе
unittest, могут нуждаться в доступе к объектуTestResult, созданному при запуске набора тестов для целей отчетности; для этого методTestRunner.run()возвращает экземплярTestResult.Экземпляры
TestResultимеют следующие атрибуты, которые будут интересны при проверке результатов запуска набора тестов:- errors¶
Список, содержащий 2-кортежи экземпляров
TestCaseи строк с форматированными трассировками. Каждый кортеж представляет тест, вызвавший неожиданное исключение.
- failures¶
Список, содержащий 2-кортежи экземпляров
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¶load_tests Protocol
Новое в версии 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):
# корневой каталог, кэшированный на экземпляре загрузчика
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 из-за невозможности соответствия имён пакетов шаблону по умолчанию.
Фикстуры классов и модулей¶Class and Module Fixtures
Фикстуры уровня класса и модуля реализуются в TestSuite. Когда
набор тестов встречает тест из нового класса, вызывается tearDownClass()
из предыдущего класса (если он есть), а затем
setUpClass() из нового класса.
Аналогично, если тест из другого модуля, отличного от предыдущего, то
запускается tearDownModule предыдущего модуля, а затем setUpModule нового модуля.
После выполнения всех тестов запускаются финальные tearDownClass и
tearDownModule.
Обратите внимание, что общие фикстуры плохо совместимы с такими возможностями, как параллельное выполнение тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.
Упорядочивание тестов по умолчанию, создаваемое загрузчиками тестов unittest, группирует
все тесты из одних и тех же модулей и классов вместе. Это приводит к тому,
что setUpClass / setUpModule (и т.д.) вызываются ровно один раз на класс и
модуль. Если изменить порядок случайным образом, так что тесты из разных модулей и
классов будут соседствовать друг с другом, то эти общие фикстуры могут
вызываться несколько раз за один прогон тестов.
Общие фикстуры не предназначены для работы с наборами тестов, имеющими
нестандартный порядок. BaseTestSuite всё ещё существует для фреймворков, которые не хотят
поддерживать общие фикстуры.
Если во время выполнения одной из общих фикстур возникает исключение,
тест помечается как ошибочный. Поскольку нет соответствующего экземпляра теста,
создаётся объект _ErrorHolder (имеющий тот же интерфейс, что и
TestCase) для представления ошибки. Если вы просто используете
стандартный исполнитель тестов unittest, эта деталь не имеет значения, но если вы
разработчик фреймворка, это может быть актуально.
setUpClass и tearDownClass¶setUpClass and 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¶setUpModule and tearDownModule
Их следует реализовывать как функции:
def setUpModule():
createConnection()
def tearDownModule():
closeConnection()
Если в setUpModule возникает исключение, то ни один тест в модуле не будет
запущен, и tearDownModule не будет выполнен. Если исключением является
SkipTest, то модуль будет помечен как пропущенный, а не как ошибочный.
Чтобы добавить код очистки, который должен выполняться даже в случае исключения, используйте
addModuleCleanup:
- unittest.addModuleCleanup(function, /, *args, **kwargs)¶
Добавляет функцию, которая будет вызвана после
tearDownModule()для очистки ресурсов, использованных во время тестового класса. Функции вызываются в обратном порядке по сравнению с порядком их добавления (LIFO). Они вызываются с теми аргументами и именованными аргументами, которые были переданы вaddModuleCleanup()при их добавлении.Если
setUpModule()завершается ошибкой, то естьtearDownModule()не вызывается, то все добавленные функции очистки всё равно будут вызваны.Новое в версии 3.8.
- classmethod unittest.enterModuleContext(cm)¶
Входит в предоставленный менеджер контекста. В случае успеха также добавляет его метод
__exit__()как функцию очистки с помощьюaddModuleCleanup()и возвращает результат метода__enter__().Новое в версии 3.11.
- unittest.doModuleCleanups()¶
Эта функция вызывается безусловно после
tearDownModule()или послеsetUpModule(), еслиsetUpModule()вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных с помощью
addModuleCleanup(). Если нужно, чтобы функции очистки вызывались доtearDownModule(), то можно вызватьdoModuleCleanups()самостоятельно.doModuleCleanups()извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любой момент.Новое в версии 3.8.
Обработка сигналов¶Signal Handling
Новое в версии 3.2.
Параметр командной строки -c/--catch для unittest
вместе с параметром catchbreak для unittest.main() обеспечивают
более удобную обработку control-C во время выполнения тестов. Когда поведение catch-break включено, control-C позволяет завершить текущий тест, после чего выполнение тестов завершается и выводятся все результаты на данный момент. Повторное нажатие control-C вызовет исключение KeyboardInterrupt обычным образом.
Обработчик сигнала control-c старается оставаться совместимым с кодом или
тестами, которые устанавливают собственный обработчик signal.SIGINT. Если обработчик unittest
вызывается, но не является установленным обработчиком signal.SIGINT,
то есть был заменён тестируемой системой и делегирован, то он вызывает
стандартный обработчик. Обычно это ожидаемое поведение для кода,
который заменяет установленный обработчик и делегирует ему. Для отдельных тестов,
где требуется unittest отключить обработку control-c, можно использовать декоратор removeHandler().
Существует несколько вспомогательных функций для разработчиков фреймворков, позволяющих включить обработку control-c в тестовых фреймворках.
- unittest.installHandler()¶
Устанавливает обработчик control-c. Когда получен сигнал
signal.SIGINT(обычно в ответ на нажатие пользователем control-c), у всех зарегистрированных результатов вызываетсяstop().
- unittest.registerResult(result)¶
Регистрирует объект
TestResultдля обработки control-c. При регистрации результата сохраняется слабая ссылка на него, поэтому это не препятствует сборке мусора объекта результата.Регистрация объекта
TestResultне имеет побочных эффектов, если обработка control-c не включена, поэтому тестовые фреймворки могут безусловно регистрировать все создаваемые ими результаты, независимо от того, включена обработка или нет.
- unittest.removeResult(result)¶
Удаляет зарегистрированный результат. После удаления результата
stop()больше не будет вызываться для этого объекта результата в ответ на control-c.
- unittest.removeHandler(function=None)¶
При вызове без аргументов эта функция удаляет обработчик control-c, если он был установлен. Эту функцию также можно использовать как тестовый декоратор для временного удаления обработчика на время выполнения теста:
@unittest.removeHandler def test_signal_handling(self): ...