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: В Python 3.11 из unittest удалена поддержка пакетов пространств имён. Она не работала начиная с 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() decorator или одним из его условных вариантов, вызвать 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предоставляет несколько методов утверждения для проверки условий и сообщения об ошибках. В следующей таблице перечислены наиболее часто используемые методы (другие методы утверждения см. в таблицах ниже):Метод
Проверяет, что
Добавлен в версии
a == ba != bbool(x) is Truebool(x) is Falsea is b3.1
a is not b3.1
x is None3.1
x is not None3.1
a in b3.1
a not in b3.1
isinstance(a, b)3.2
not isinstance(a, b)3.2
Все методы утверждения принимают аргумент msg, который при указании используется как сообщение об ошибке (см. также
longMessage). Обратите внимание, что аргумент-ключевое слово msg можно передать методамassertRaises(),assertRaisesRegex(),assertWarns()иassertWarnsRegex()только при использовании их в качестве менеджеров контекста.-
assertEqual(first, second, msg=None) -
Проверяет, что first и second равны. Если значения не равны, тест завершается неудачей.
Кроме того, если first и second имеют совершенно одинаковый тип, который является одним из типов 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
-
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.
-
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.12.4: 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, созданному при запуске набора тестов, для подготовки отчётов; для этой цели экземплярTestResultвозвращается методомTestRunner.run().Экземпляры
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()для освобождения ресурсов, использованных во время тестирования класса. Функции вызываются в порядке, обратном порядку их добавления (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.
Обработка сигналов
Добавлено в версии 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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/unittest.html