unittest — Фреймворк модульного тестирования
Исходный код: Lib/unittest/__init__.py
(Если вы уже знакомы с основными понятиями тестирования, можно перейти к списку методов assert.)
Фреймворк модульного тестирования unittest изначально был создан под влиянием JUnit и похож на основные фреймворки модульного тестирования в других языках. Он поддерживает автоматизацию тестирования, совместное использование кода подготовки и завершения для тестов, объединение тестов в коллекции и независимость тестов от фреймворка формирования отчётов.
Для этого unittest поддерживает несколько важных концепций в объектно-ориентированной форме:
- тестовый стенд
-
Тестовый стенд представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, и любые связанные с этим действия по очистке. Например, это может быть создание временных баз данных или баз данных-прокси, каталогов либо запуск серверного процесса.
- тестовый пример
-
Тестовый пример — это отдельная единица тестирования. Он проверяет конкретный ответ на заданный набор входных данных.
unittestпредоставляет базовый классTestCase, который можно использовать для создания новых тестовых примеров. - набор тестов
-
Набор тестов — это коллекция тестовых примеров, наборов тестов или того и другого. Он используется для объединения тестов, которые следует выполнять вместе.
- средство запуска тестов
-
Средство запуска тестов — это компонент, который координирует выполнение тестов и сообщает пользователю результат. Средство запуска может использовать графический или текстовый интерфейс либо возвращать специальное значение, указывающее результаты выполнения тестов.
См. также
-
Moduledoctest -
Другой модуль поддержки тестирования с совершенно иным подходом.
- Простое тестирование в Smalltalk: с использованием шаблонов
-
Оригинальная статья Кента Бека о фреймворках тестирования, использующих шаблон, общий для
unittest. - pytest
-
Сторонний фреймворк тестирования с более лаконичным синтаксисом для написания тестов. Например,
assert func(10) == 42. - Классификация средств тестирования Python
-
Обширный список средств тестирования Python, включая фреймворки функционального тестирования и библиотеки имитационных объектов.
- Список рассылки Testing in Python
-
Группа по интересам для обсуждения тестирования и средств тестирования в Python.
Скрипт Tools/unittestgui/unittestgui.py в дистрибутиве исходного кода Python — это графический инструмент для обнаружения и запуска тестов. Он предназначен главным образом для упрощения работы тех, кто только начинает заниматься модульным тестированием. Для производственных сред рекомендуется запускать тесты с помощью системы непрерывной интеграции, например Buildbot, Jenkins, GitHub Actions или 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.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) теперь считается устаревшим.
Интерфейс командной строки
Модуль 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 -
Нажатие 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 -
Показывать локальные переменные в трассировках стека.
-
--durations N -
Показывать N самых медленных тестовых примеров (N=0 — все).
Добавлено в версии 3.2: Добавлены параметры командной строки -b, -c и -f.
Добавлено в версии 3.5: Параметр командной строки --locals.
Добавлено в версии 3.7: Параметр командной строки -k.
Добавлено в версии 3.12: Параметр командной строки --durations.
Командную строку также можно использовать для обнаружения тестов — запуска всех тестов проекта или только их подмножества.
Обнаружение тестов
Добавлено в версии 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/ <-- current directory # namespace/ # mypkg/ # __init__.py # test_mypkg.py python -m unittest discover -s namespace.mypkg -t .
Организация кода тестов
Основные строительные блоки модульного тестирования — это тестовые примеры, то есть отдельные сценарии, которые необходимо подготовить и проверить на корректность. В 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, в любом случае должны находиться в отдельных модулях, так почему бы не придерживаться единого подхода?
- Если стратегия тестирования изменится, исходный код не придётся менять.
Повторное использование старого кода тестов
Некоторые пользователи могут обнаружить, что у них уже есть код тестирования, который хотелось бы запускать с помощью 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.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().
Различение итераций теста с помощью под-тестов
Добавлено в версии 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.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
Классы и функции
В этом разделе подробно описан 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 для проверки условий и сообщения об ошибках. В следующей таблице перечислены наиболее часто используемые методы (другие методы 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 (или не является). cls может быть классом или кортежем классов, как поддерживается функцией
isinstance(). Чтобы проверить точное совпадение типа, используйтеassertIs(type(obj), cls).Добавлено в версии 3.2.
Следующие методы позволяют также проверять возникновение исключений и предупреждений, а также появление сообщений в журнале:
Метод
Проверяет, что
Добавлен в
fun(*args, **kwds)вызывает исключение excfun(*args, **kwds)вызывает исключение exc, а сообщение соответствует регулярному выражению r3.1
fun(*args, **kwds)вызывает предупреждение warn3.2
fun(*args, **kwds)вызывает предупреждение warn, а сообщение соответствует регулярному выражению r3.2
В блоке
withрегистрируются сообщения от logger с уровнем не ниже level3.4
-
The with block does not log on -
logger с уровнем не ниже level
3.10
-
assertRaises(exception, callable, *args, **kwds) - assertRaises(exception, *, msg=None)
-
Проверяет, что при вызове callable с любыми позиционными или именованными аргументами, также переданными в
assertRaises(), возникает исключение. Тест проходит, если возникает исключение exception, завершается ошибкой, если возникает другое исключение, и проваливается, если исключение не возникает. Чтобы перехватить любое исключение из группы, в качестве exception можно передать кортеж, содержащий классы исключений.Если указаны только аргумент exception и, возможно, msg, возвращается менеджер контекста, чтобы проверяемый код можно было записать непосредственно, а не оформлять в виде функции:
with self.assertRaises(SomeException): do_something()При использовании в качестве менеджера контекста
assertRaises()принимает дополнительный именованный аргумент msg.Менеджер контекста сохраняет перехваченный объект исключения в своём атрибуте
exception. Это может быть полезно, если требуется выполнить дополнительные проверки возникшего исключения:with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3)Изменено в версии 3.1: Добавлена возможность использовать
assertRaises()в качестве менеджера контекста.Изменено в версии 3.2: Добавлен атрибут
exception.Изменено в версии 3.3: При использовании в качестве менеджера контекста добавлен именованный аргумент msg.
-
assertRaisesRegex(exception, regex, callable, *args, **kwds) - assertRaisesRegex(exception, regex, *, msg=None)
-
Как
assertRaises(), но дополнительно проверяет, что строковое представление возникшего исключения соответствует regex. regex может быть объектом регулярного выражения или строкой с регулярным выражением, подходящим для использования функциейre.search(). Примеры:self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$", int, 'XYZ')или:
with self.assertRaisesRegex(ValueError, 'literal'): int('XYZ')Добавлено в версии 3.1: Добавлен под именем
assertRaisesRegexp.Изменено в версии 3.2: Переименован в
assertRaisesRegex().Изменено в версии 3.3: При использовании в качестве менеджера контекста добавлен именованный аргумент msg.
-
assertWarns(warning, callable, *args, **kwds) - assertWarns(warning, *, msg=None)
-
Проверяет, что при вызове callable с любыми позиционными или именованными аргументами, также переданными в
assertWarns(), возникает предупреждение. Тест проходит, если возникает предупреждение warning, и проваливается, если этого не происходит. Любое исключение считается ошибкой. Чтобы перехватить любое предупреждение из группы, в качестве warnings можно передать кортеж, содержащий классы предупреждений.Если указаны только аргумент warning и, возможно, msg, возвращается менеджер контекста, чтобы проверяемый код можно было записать непосредственно, а не оформлять в виде функции:
with self.assertWarns(SomeWarning): do_something()При использовании в качестве менеджера контекста
assertWarns()принимает дополнительный именованный аргумент msg.Менеджер контекста сохраняет перехваченный объект предупреждения в атрибуте
warning, а строку исходного кода, вызвавшую предупреждение, — в атрибутахfilenameиlineno. Это может быть полезно, если требуется выполнить дополнительные проверки перехваченного предупреждения:with self.assertWarns(SomeWarning) as cm: do_something() self.assertIn('myfile.py', cm.filename) self.assertEqual(320, cm.lineno)Этот метод работает независимо от действующих на момент вызова фильтров предупреждений.
Добавлено в версии 3.2.
Изменено в версии 3.3: При использовании в качестве менеджера контекста добавлен именованный аргумент msg.
-
assertWarnsRegex(warning, regex, callable, *args, **kwds) - assertWarnsRegex(warning, regex, *, msg=None)
-
Как
assertWarns(), но дополнительно проверяет, что сообщение возникшего предупреждения соответствует regex. regex может быть объектом регулярного выражения или строкой с регулярным выражением, подходящим для использования функциейre.search(). Пример:self.assertWarnsRegex(DeprecationWarning, r'legacy_function\(\) is deprecated', legacy_function, 'XYZ')или:
with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'): frobnicate('/etc/passwd')Добавлено в версии 3.2.
Изменено в версии 3.3: При использовании в качестве менеджера контекста добавлен именованный аргумент msg.
-
assertLogs(logger=None, level=None) -
Менеджер контекста для проверки того, что для logger или одного из его дочерних регистраторов записано хотя бы одно сообщение с уровнем не ниже указанного level.
Если указан, logger должен быть объектом
logging.Loggerили объектомstr, содержащим имя регистратора. По умолчанию используется корневой регистратор, который перехватывает все сообщения, не заблокированные дочерними регистраторами с отключённой передачей сообщений родительскому регистратору.Если указан, level должен быть числовым уровнем журналирования или его строковым эквивалентом (например,
"ERROR"илиlogging.ERROR). По умолчанию используетсяlogging.INFO.Тест проходит, если хотя бы одно сообщение, выведенное внутри блока
with, соответствует условиям для logger и level; в противном случае тест завершается неудачно.Объект, возвращаемый менеджером контекста, — это вспомогательный объект для записи, который отслеживает соответствующие сообщения журнала. У него есть два атрибута:
-
records -
Список объектов
logging.LogRecord, соответствующих сообщениям журнала.
-
output -
Список объектов
strс отформатированным выводом соответствующих сообщений.
Пример:
with self.assertLogs('foo', level='INFO') as cm: logging.getLogger('foo').info('first message') logging.getLogger('foo.bar').error('second message') self.assertEqual(cm.output, ['INFO:foo:first message', 'ERROR:foo.bar:second message'])Добавлено в версии 3.4.
-
-
assertNoLogs(logger=None, level=None) -
Менеджер контекста для проверки того, что для logger или одного из его дочерних регистраторов не записано ни одного сообщения с уровнем не ниже указанного level.
Если указан, logger должен быть объектом
logging.Loggerили объектомstr, содержащим имя регистратора. По умолчанию используется корневой регистратор, который перехватывает все сообщения.Если указан, level должен быть числовым уровнем журналирования или его строковым эквивалентом (например,
"ERROR"илиlogging.ERROR). По умолчанию используетсяlogging.INFO.В отличие от
assertLogs(), менеджер контекста ничего не возвращает.Добавлено в версии 3.10.
Существуют также другие методы для выполнения более специализированных проверок, например:
-
Метод
Проверяет, что
Добавлен в
round(a-b, 7) == 0round(a-b, 7) != 0a > b3.1
a >= b3.1
a < b3.1
a <= b3.1
r.search(s)3.1
not r.search(s)3.2
a и b содержат одинаковые элементы в одинаковом количестве, независимо от их порядка.
3.2
-
assertAlmostEqual(first, second, places=7, msg=None, delta=None) -
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None) -
Проверяет, что first и second приблизительно (или не приблизительно) равны: вычисляет разность, округляет её до заданного количества десятичных разрядов (по умолчанию 7) и сравнивает с нулём. Обратите внимание: эти методы округляют значения до заданного количества десятичных разрядов (то есть так же, как функция
round()), а не до значащих цифр.Если вместо places задано delta, разность между first и second должна быть меньше или равна (или больше) delta.
Одновременная передача delta и places вызывает исключение
TypeError.Изменено в версии 3.2:
assertAlmostEqual()автоматически считает объекты приблизительно равными, если они сравниваются как равные.assertNotAlmostEqual()автоматически завершается неудачей, если объекты сравниваются как равные. Добавлен именованный аргумент delta.
-
assertGreater(first, second, msg=None) -
assertGreaterEqual(first, second, msg=None) -
assertLess(first, second, msg=None) -
assertLessEqual(first, second, msg=None) -
Проверяет, что first соответственно больше, больше или равно, меньше или меньше или равно second — в зависимости от имени метода. В противном случае тест завершится неудачей:
>>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4"
Добавлено в версии 3.1.
-
assertRegex(text, regex, msg=None) -
assertNotRegex(text, regex, msg=None) -
Проверяет, соответствует ли поиск по regex тексту text (или не соответствует ему). В случае неудачи сообщение об ошибке будет содержать шаблон и text (или шаблон и часть text, которой он неожиданно соответствует). regex может быть объектом регулярного выражения или строкой с регулярным выражением, подходящим для использования функцией
re.search().Добавлено в версии 3.1: Добавлен под именем
assertRegexpMatches.Изменено в версии 3.2: Метод
assertRegexpMatches()переименован вassertRegex().Добавлено в версии 3.2:
assertNotRegex().
-
assertCountEqual(first, second, msg=None) -
Проверяет, что последовательность first содержит те же элементы, что и second, независимо от их порядка. Если это не так, будет создано сообщение об ошибке со списком различий между последовательностями.
При сравнении first и second повторяющиеся элементы не игнорируются. Метод проверяет, что каждый элемент встречается в обеих последовательностях одинаковое количество раз. Эквивалентен:
assertEqual(Counter(list(first)), Counter(list(second))), но также работает с последовательностями нехешируемых объектов.Добавлено в версии 3.2.
Метод
assertEqual()передаёт проверку равенства объектов одного типа разным методам, предназначенным для конкретных типов. Такие методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощьюaddTypeEqualityFunc():-
addTypeEqualityFunc(typeobj, function) -
Регистрирует метод для конкретного типа, вызываемый методом
assertEqual()для проверки равенства двух объектов с точно одинаковым типом typeobj (не подклассов). function должен принимать два позиционных аргумента и третий именованный аргумент msg=None, как иassertEqual(). При обнаружении неравенства первых двух параметров он должен вызывать исключениеself.failureException(msg), по возможности предоставляя полезную информацию и подробно объясняя различия в сообщении об ошибке.Добавлено в версии 3.1.
Список методов для конкретных типов, автоматически используемых методом
assertEqual(), приведён в следующей таблице. Обычно нет необходимости вызывать эти методы напрямую.Метод
Используется для сравнения
Добавлен в
строк
3.1
последовательностей
3.1
списков
3.1
кортежей
3.1
множеств или неизменяемых множеств
3.1
словарей
3.1
-
assertMultiLineEqual(first, second, msg=None) -
Проверяет, что многострочная строка first равна строке second. Если строки не равны, в сообщение об ошибке будет включено их сравнение с выделением различий. Этот метод используется по умолчанию при сравнении строк с помощью
assertEqual().Добавлено в версии 3.1.
-
assertSequenceEqual(first, second, msg=None, seq_type=None) -
Проверяет равенство двух последовательностей. Если задан seq_type, и first, и second должны быть экземплярами seq_type, иначе будет вызвана ошибка. Если последовательности различаются, создаётся сообщение об ошибке, показывающее различия между ними.
Этот метод не вызывается напрямую методом
assertEqual(), но используется для реализации методовassertListEqual()иassertTupleEqual().Добавлено в версии 3.1.
-
assertListEqual(first, second, msg=None) -
assertTupleEqual(first, second, msg=None) -
Проверяет равенство двух списков или кортежей. Если они не равны, создаётся сообщение об ошибке, в котором показаны только различия между ними. Также вызывается ошибка, если тип одного из параметров неверен. Эти методы используются по умолчанию при сравнении списков или кортежей с помощью
assertEqual().Добавлено в версии 3.1.
-
assertSetEqual(first, second, msg=None) -
Проверяет равенство двух множеств. Если они не равны, создаётся сообщение об ошибке со списком различий между множествами. Этот метод используется по умолчанию при сравнении множеств или неизменяемых множеств с помощью
assertEqual().Проверка завершается неудачей, если у first или second отсутствует метод
set.difference().Добавлено в версии 3.1.
-
assertDictEqual(first, second, msg=None) -
Проверяет равенство двух словарей. Если они не равны, создаётся сообщение об ошибке, показывающее различия между словарями. Этот метод используется по умолчанию для сравнения словарей при вызове
assertEqual().Добавлено в версии 3.1.
Наконец,
TestCaseпредоставляет следующие методы и атрибуты:-
fail(msg=None) -
Безусловно сообщает о неудаче теста, используя msg или
Noneв качестве сообщения об ошибке.
-
failureException -
Этот атрибут класса задаёт исключение, вызываемое методом теста. Если тестовой среде нужно использовать специализированное исключение, возможно, для передачи дополнительной информации, это исключение следует унаследовать, чтобы обеспечить совместимость с тестовой средой. Начальное значение этого атрибута —
AssertionError.
-
longMessage -
Этот атрибут класса определяет поведение при передаче пользовательского сообщения об ошибке в качестве аргумента msg методу assertXYY, завершившемуся неудачей. По умолчанию используется значение
True. В этом случае пользовательское сообщение добавляется в конец стандартного сообщения об ошибке. Если задано значениеFalse, пользовательское сообщение заменяет стандартное.Настройку класса можно переопределить для отдельных методов теста, присвоив атрибуту экземпляра self.longMessage значение
TrueилиFalseперед вызовом методов assert.Настройка класса сбрасывается перед каждым вызовом теста.
Добавлено в версии 3.1.
-
maxDiff -
Этот атрибут задаёт максимальную длину различий, выводимых методами assert при неудачной проверке. По умолчанию она составляет 80*8 символов. Атрибут влияет на следующие методы assert:
assertSequenceEqual()(включая все методы сравнения последовательностей, делегирующие ему выполнение),assertDictEqual()иassertMultiLineEqual().Если установить для
maxDiffзначениеNone, максимальная длина различий не ограничивается.Добавлено в версии 3.2.
Тестовые среды могут использовать следующие методы для сбора информации о тесте:
-
countTestCases() -
Возвращает количество тестов, представленных этим тестовым объектом. Для экземпляров
TestCaseэто значение всегда равно1.
-
defaultTestResult() -
Возвращает экземпляр класса результатов тестирования, который следует использовать для этого класса тестовых случаев (если методу
run()не передан другой экземпляр результата).Для экземпляров
TestCaseэто всегда будет экземплярTestResult; подклассамTestCaseследует при необходимости переопределить этот метод.
-
id() -
Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя метода теста, включая имена модуля и класса.
-
shortDescription() -
Возвращает описание теста или
None, если описание не задано. Реализация этого метода по умолчанию возвращает первую строку docstring метода теста, если она есть, илиNone.Изменено в версии 3.1: В версии 3.1 поведение изменили: имя теста добавлялось в краткое описание даже при наличии docstring. Это вызвало проблемы совместимости с расширениями unittest, поэтому в Python 3.2 добавление имени теста перенесли в
TextTestResult.
-
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.
-
loop_factory -
loop_factory, передаваемый в
asyncio.Runner. Переопределите его в подклассах с помощьюasyncio.EventLoop, чтобы не использовать систему политик asyncio.Добавлено в версии 3.13.
-
async asyncSetUp() -
Метод, вызываемый для подготовки тестовой фикстуры. Он вызывается после
setUp(). Этот метод вызывается непосредственно перед вызовом тестового метода; любое исключение, выброшенное этим методом, кромеAssertionErrorилиSkipTest, будет считаться ошибкой, а не провалом теста. Реализация по умолчанию ничего не делает.
-
async asyncTearDown() -
Метод, вызываемый сразу после вызова тестового метода и записи результата. Он вызывается перед
tearDown(). Этот метод вызывается, даже если тестовый метод выбросил исключение, поэтому при реализации в подклассах может потребоваться особенно тщательно проверять внутреннее состояние. Любое исключение, выброшенное этим методом, кромеAssertionErrorилиSkipTest, будет считаться дополнительной ошибкой, а не провалом теста (тем самым увеличивая общее число зарегистрированных ошибок). Этот метод вызывается только в том случае, еслиasyncSetUp()завершается успешно, независимо от результата тестового метода. Реализация по умолчанию ничего не делает.
-
addAsyncCleanup(function, /, *args, **kwargs) -
Этот метод принимает корутину, которую можно использовать в качестве функции очистки.
-
async 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среду тестирования.
Группировка тестов
-
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) -
Возвращает набор всех тестовых случаев, содержащихся в указанном модуле. Этот метод ищет в module классы, производные от
TestCase, и создаёт экземпляр класса для каждого определённого в нём тестового метода.Примечание
Иерархия классов, производных от
TestCase, может быть удобна для совместного использования фикстур и вспомогательных функций. Однако определение тестовых методов в базовых классах, которые не предназначены для непосредственного создания экземпляров, плохо сочетается с этим методом. Тем не менее такой подход может быть полезен, если фикстуры различаются и определены в подклассах.Если модуль предоставляет функцию
load_tests, она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это протокол load_tests. Аргумент pattern передаётся третьим аргументом вload_tests.Изменено в версии 3.2: Добавлена поддержка
load_tests.Изменено в версии 3.5: Добавлена поддержка аргумента pattern, доступного только по ключевому слову.
Изменено в версии 3.12: Удалён недокументированный и неофициальный параметр use_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 относительно указанного 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 (используется сопоставление с шаблонами в стиле оболочки). Загружаются только имена модулей, которые можно импортировать (то есть являющиеся допустимыми идентификаторами Python).
Все модули с тестами должны импортироваться из верхнего уровня проекта. Если начальный каталог не является каталогом верхнего уровня, необходимо отдельно указать top_level_dir.
Если импорт модуля завершается ошибкой, например из-за синтаксической ошибки, она будет зарегистрирована как одна ошибка, а поиск продолжится. Если ошибка импорта вызвана возбуждением
SkipTest, она будет зарегистрирована как пропуск, а не как ошибка.Если найден пакет (каталог, содержащий файл с именем
__init__.py), пакет будет проверен на наличие функцииload_tests. Если она существует, будет вызванаpackage.load_tests(loader, tests, pattern). При поиске тестов обеспечивается, что пакет проверяется на наличие тестов только один раз за вызов, даже если сама функция load_tests вызываетloader.discover.Если существует
load_tests, поиск не выполняет рекурсивный обход пакета: за загрузку всех тестов пакета отвечаетload_tests.Шаблон намеренно не сохраняется в качестве атрибута загрузчика, чтобы пакеты могли продолжать поиск самостоятельно.
top_level_dir сохраняется внутри и используется как значение по умолчанию для всех вложенных вызовов
discover(). То есть если функция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 её официально удалили.
Изменено в версии 3.13: top_level_dir сохраняется только на время вызова discover.
Следующие атрибуты
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, помеченных как ожидаемые неудачи, но завершившихся успешно.
-
collectedDurations -
Список 2-кортежей с именами тестовых случаев и числами с плавающей точкой, представляющими время выполнения каждого запущенного теста.
Добавлено в версии 3.12.
-
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, если среди тестов, помеченных декораторомexpectedFailure(), есть случаиunexpectedSuccesses.
-
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.
-
addDuration(test, elapsed) -
Вызывается по завершении тестового случая. elapsed — время в секундах, включающее выполнение функций очистки.
Добавлено в версии 3.12.
-
-
class unittest.TextTestResult(stream, descriptions, verbosity, *, durations=None) -
Конкретная реализация
TestResult, используемая классомTextTestRunner. Для обеспечения совместимости при изменении интерфейса подклассы должны принимать**kwargs.Добавлено в версии 3.2.
Изменено в версии 3.12: Добавлен именованный параметр durations.
-
unittest.defaultTestLoader -
Экземпляр класса
TestLoader, предназначенный для совместного использования. Если настраиватьTestLoaderне требуется, этот экземпляр можно использовать вместо многократного создания новых экземпляров.
-
class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False, durations=None) -
Базовая реализация средства запуска тестов, выводящая результаты в поток. Если stream —
None, значение по умолчанию, в качестве выходного потока используетсяsys.stderr. Этот класс имеет несколько настраиваемых параметров, но в целом он очень прост. Графические приложения, запускающие наборы тестов, должны предоставлять альтернативные реализации. Такие реализации должны принимать**kwargs, поскольку интерфейс создания средств запуска изменяется при добавлении возможностей в unittest.По умолчанию это средство запуска показывает
DeprecationWarning,PendingDeprecationWarning,ResourceWarningиImportWarning, даже если они по умолчанию игнорируются. Это поведение можно переопределить с помощью параметров Python-Wdили-Wa(см. раздел Управление предупреждениями), оставив warnings равнымNone.Изменено в версии 3.2: Добавлен параметр warnings.
Изменено в версии 3.2: Поток по умолчанию устанавливается в
sys.stderrво время создания экземпляра, а не во время импорта.Изменено в версии 3.5: Добавлен параметр tb_locals.
Изменено в версии 3.12: Добавлен параметр durations.
-
_makeResult() -
Этот метод возвращает экземпляр
TestResult, используемый методомrun(). Он не предназначен для прямого вызова, но может быть переопределён в подклассах для предоставления пользовательскогоTestResult._makeResult()создаёт экземпляр класса или вызываемого объекта, переданного в конструкторTextTestRunnerв качестве аргументаresultclass. Еслиresultclassне указан, по умолчанию используетсяTextTestResult. Класс результата создаётся со следующими аргументами: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()с кодом завершения, указывающим на успех (0) или неудачу (1) выполненных тестов. Код завершения 5 означает, что тесты не запускались или были пропущены.Аргумент testLoader должен быть экземпляром
TestLoader; по умолчанию используетсяdefaultTestLoader.mainможно использовать в интерактивном интерпретаторе, передав аргументexit=False. Результат будет выведен в стандартный поток вывода, а вызоваsys.exit()не произойдёт:>>> from unittest import main >>> main(module='test_module', exit=False)
Параметры failfast, catchbreak и buffer действуют так же, как одноимённые параметры командной строки.
Аргумент warnings задаёт фильтр предупреждений, используемый во время выполнения тестов. Если он не задан, сохраняется значение
None, если программе python передан параметр-W(см. раздел Управление предупреждениями); в противном случае ему присваивается значение'default'.Вызов
mainвозвращает объект с атрибутомresult, содержащим результат выполненных тестов в видеunittest.TestResult.Изменено в версии 3.1: Добавлен параметр exit.
Изменено в версии 3.2: Добавлены параметры verbosity, failfast, catchbreak, buffer и warnings.
Изменено в версии 3.4: Параметр defaultTest теперь также принимает итерируемый объект с именами тестов.
Протокол load_tests
Добавлено в версии 3.2.
Модули или пакеты могут настраивать загрузку тестов из них при обычном запуске тестов или поиске тестов, реализовав функцию с именем load_tests.
Если модуль с тестами определяет load_tests, она будет вызвана методом TestLoader.loadTestsFromModule() со следующими аргументами:
load_tests(loader, standard_tests, pattern)
где pattern напрямую передаётся из loadTestsFromModule. По умолчанию используется None.
Функция должна возвращать TestSuite.
loader — это экземпляр TestLoader, выполняющий загрузку. standard_tests — тесты, которые по умолчанию загружались бы из модуля. Обычно модули с тестами хотят лишь добавлять тесты к стандартному набору или удалять их из него. Третий аргумент используется при загрузке пакетов в рамках поиска тестов.
Типичная функция load_tests, загружающая тесты из определённого набора классов TestCase, может выглядеть так:
test_cases = (TestCase1, TestCase2, TestCase3)
def load_tests(loader, tests, pattern):
suite = TestSuite()
for test_class in test_cases:
tests = loader.loadTestsFromTestCase(test_class)
suite.addTests(tests)
return suite
Если поиск начинается в каталоге, содержащем пакет, — из командной строки или вызовом TestLoader.discover(), — в пакете __init__.py будет выполнена проверка на наличие load_tests. Если такой функции нет, поиск продолжится внутри пакета, как если бы он был обычным каталогом. В противном случае поиск тестов пакета будет возложен на load_tests, которая вызывается со следующими аргументами:
load_tests(loader, standard_tests, pattern)
Эта функция должна возвращать TestSuite, представляющий все тесты пакета. (standard_tests будет содержать только тесты, собранные из __init__.py.)
Поскольку шаблон передаётся в load_tests, пакет может продолжить поиск тестов (и при необходимости изменить его). Функция load_tests для пакета с тестами, которая ничего не делает, может выглядеть так:
def load_tests(loader, standard_tests, pattern):
# top level directory cached on loader instance
this_dir = os.path.dirname(__file__)
package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
standard_tests.addTests(package_tests)
return standard_tests
Изменено в версии 3.5: Поиск больше не проверяет имена пакетов на соответствие шаблону pattern, поскольку имена пакетов не могут соответствовать шаблону по умолчанию.
Фикстуры классов и модулей
Фикстуры на уровне классов и модулей реализованы в TestSuite. Когда набор тестов встречает тест нового класса, вызывается tearDownClass() предыдущего класса (если он есть), а затем setUpClass() нового класса.
Аналогично, если тест относится к модулю, отличному от модуля предыдущего теста, запускается tearDownModule предыдущего модуля, а затем setUpModule нового модуля.
После выполнения всех тестов запускаются заключительные tearDownClass и tearDownModule.
Учтите, что общие фикстуры плохо сочетаются с такими возможными функциями, как параллельное выполнение тестов, и нарушают изоляцию тестов. Используйте их с осторожностью.
По умолчанию загрузчики тестов unittest упорядочивают тесты так, чтобы все тесты одного модуля и класса шли подряд. В результате setUpClass / setUpModule (и т. д.) вызываются ровно один раз для каждого класса и модуля. Если изменить порядок так, чтобы тесты из разных модулей и классов чередовались, эти функции общих фикстур могут вызываться несколько раз за один запуск тестов.
Общие фикстуры не предназначены для работы с наборами, имеющими нестандартный порядок. Для фреймворков, не поддерживающих общие фикстуры, по-прежнему существует BaseTestSuite.
Если во время выполнения одной из функций общей фикстуры возникает исключение, тест отмечается как завершившийся ошибкой. Поскольку соответствующего экземпляра теста нет, для представления ошибки создаётся объект _ErrorHolder (с тем же интерфейсом, что и у TestCase). Если вы используете стандартное средство запуска тестов unittest, эта деталь не имеет значения, однако авторам фреймворков она может быть важна.
setUpClass и tearDownClass
Их необходимо реализовать как методы класса:
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()
Если вы хотите, чтобы вызывались setUpClass и tearDownClass базовых классов, необходимо самостоятельно вызвать их. Реализации в TestCase пусты.
Если во время выполнения setUpClass возникает исключение, тесты класса не запускаются, а tearDownClass не выполняется. Для пропущенных классов не выполняются setUpClass и tearDownClass. Если исключение относится к типу SkipTest, класс будет отмечен как пропущенный, а не как завершившийся ошибкой.
setUpModule и tearDownModule
Их следует реализовать как функции:
def setUpModule():
createConnection()
def tearDownModule():
closeConnection()
Если во время выполнения setUpModule возникает исключение, ни один тест модуля не будет запущен, а tearDownModule не выполнится. Если исключение относится к типу SkipTest, модуль будет отмечен как пропущенный, а не как завершившийся ошибкой.
Чтобы добавить код очистки, который должен выполняться даже в случае исключения, используйте addModuleCleanup:
-
unittest.addModuleCleanup(function, /, *args, **kwargs) -
Добавляет функцию, которая будет вызвана после
tearDownModule()для очистки ресурсов, использованных во время тестирования класса. Функции вызываются в порядке, обратном порядку их добавления (последним добавлен — первым выполнен). При вызове им передаются позиционные и именованные аргументы, указанные при добавлении вaddModuleCleanup().Если
setUpModule()завершается с ошибкой, то естьtearDownModule()не вызывается, все добавленные функции очистки всё равно будут вызваны.Добавлено в версии 3.8.
-
unittest.enterModuleContext(cm) -
Входит в переданный менеджер контекста. В случае успеха добавляет его метод
__exit__()как функцию очистки с помощьюaddModuleCleanup()и возвращает результат метода__enter__().Добавлено в версии 3.11.
-
unittest.doModuleCleanups() -
Эта функция безусловно вызывается после
tearDownModule()или послеsetUpModule(), еслиsetUpModule()вызывает исключение.Она отвечает за вызов всех функций очистки, добавленных с помощью
addModuleCleanup(). Если необходимо вызвать функции очистки доtearDownModule(), можно самостоятельно вызватьdoModuleCleanups().doModuleCleanups()по одной снимает методы со стека функций очистки, поэтому её можно вызвать в любой момент.Добавлено в версии 3.8.
Обработка сигналов
Добавлено в версии 3.2.
Параметр командной строки unittest -c/--catch, а также параметр catchbreak функции unittest.main() обеспечивают более удобную обработку нажатия Ctrl-C во время выполнения тестов. При включённой обработке прерывания Ctrl-C позволяет завершить текущий тест, после чего выполнение тестов прекращается и выводятся все полученные на данный момент результаты. Повторное нажатие Ctrl-C вызовет KeyboardInterrupt обычным образом.
Обработчик сигнала Ctrl-C старается сохранять совместимость с кодом и тестами, устанавливающими собственный обработчик signal.SIGINT. Если вызывается обработчик unittest, но он не является установленным обработчиком signal.SIGINT, то есть система под тестированием заменила его и передала ему управление, вызывается обработчик по умолчанию. Обычно именно такого поведения ожидает код, который заменяет установленный обработчик и передаёт ему управление. Для отдельных тестов, которым требуется отключить обработку Ctrl-C с помощью unittest, можно использовать декоратор 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–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/unittest.html