unittest — Фреймворк для модульного тестирования
Исходный код: Lib/unittest/__init__.py
(Если вы уже знакомы с основными понятиями тестирования, можете перейти к списку методов assert.)
Фреймворк unittest для модульного тестирования изначально был вдохновлён JUnit и имеет схожую структуру с основными фреймворками модульного тестирования других языков. Он поддерживает автоматизацию тестирования, совместное использование кода подготовки и завершения для тестов, агрегацию тестов в коллекции и независимость тестов от фреймворка отчётов.
Для достижения этого, unittest поддерживает некоторые важные концепции объектно-ориентированным способом:
- Тестовая фикстура
-
Тестовая фикстура представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, а также любые связанные действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск процесса сервера.
- Тестовый случай
-
Тестовый случай — это отдельная единица тестирования. Он проверяет определённый ответ на конкретный набор входных данных.
unittestпредоставляет базовый класс,TestCase, который можно использовать для создания новых тестовых случаев. - Тестовый набор
-
Тестовый набор — это коллекция тестовых случаев, тестовых наборов или того и другого. Он используется для агрегации тестов, которые должны выполняться вместе.
- Запускатель тестов
-
Запускатель тестов — это компонент, который координирует выполнение тестов и предоставляет результат пользователю. Запускатель может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение для указания результатов выполнения тестов.
См. также
-
Moduledoctest -
Другой модуль поддержки тестирования с совершенно другим подходом.
- Simple Smalltalk Testing: With Patterns
-
Оригинальная статья Кента Бека о фреймворках для тестирования, использующих паттерны, применяемые в
unittest. - pytest
-
Фреймворк для модульного тестирования сторонних разработчиков с более лёгким синтаксисом для написания тестов. Например,
assert func(10) == 42. - Классификация инструментов для тестирования Python
-
Развёрнутый список инструментов для тестирования Python, включая фреймворки функционального тестирования и библиотеки объектов-моков.
- Список рассылки по тестированию в Python
-
Группа по интересам для обсуждения тестирования и инструментов для тестирования в Python.
Скрипт Tools/unittestgui/unittestgui.py в дистрибутиве исходного кода Python — это графический инструмент для обнаружения и запуска тестов. В основном он предназначен для удобства использования для тех, кто только начинает работать с модульным тестированием. Для производственных сред рекомендуется использовать системы непрерывной интеграции, такие как Buildbot, Jenkins, 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 -
Ctrl-C во время выполнения теста ожидает завершения текущего теста, а затем сообщает все результаты до этого момента. Второй Ctrl-C вызывает обычное исключение
KeyboardInterrupt.См. Обработка сигналов для функций, предоставляющих эту функциональность.
-
-f, --failfast -
Остановка выполнения теста при первой ошибке или сбое.
-
-k -
Запускаются только те тестовые методы и классы, которые соответствуют шаблону или подстроке. Этот параметр можно использовать несколько раз, в этом случае включаются все тестовые случаи, которые соответствуют любому из заданных шаблонов.
Шаблоны, содержащие символ подстановки (
*), сопоставляются с именем теста с помощьюfnmatch.fnmatchcase(); в противном случае используется простое сопоставление подстроки, чувствительной к регистру.Шаблоны сопоставляются с полным квалифицированным именем тестового метода, импортированным загрузчиком тестов.
Например,
-k fooсоответствуетfoo_tests.SomeTest.test_something,bar_tests.SomeTest.test_foo, но неbar_tests.FooTest.test_something.
-
--locals -
Отображение локальных переменных в отслеживающих отладочных выводах.
-
--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 protocol.
Изменено в версии 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 предоставляет механизм для этого: тестовый набор, представленный классом unittest’s TestSuite. В большинстве случаев вызов unittest.main() сделает всё правильно, собрав и выполнив все тестовые случаи модуля.
Однако, если вы хотите настроить создание тестового набора самостоятельно:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_widget_size'))
suite.addTest(WidgetTestCase('test_widget_resize'))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
Вы можете разместить определения тестовых случаев и тестовых наборов в тех же модулях, что и код, который они тестируют (например, widget.py), но есть несколько преимуществ размещения тестового кода в отдельном модуле, например, test_widget.py:
- Модуль тестов может запускаться автономно из командной строки.
- Тестовый код легче отделить от распространяемого кода.
- Меньше искушения изменять тестовый код, чтобы он подходил к тестируемому коду без веской причины.
- Тестовый код должен изменяться гораздо реже, чем код, который он тестирует.
- Тестируемый код можно проще рефакторить.
- Тесты для модулей, написанных на C, должны быть в отдельных модулях, так что почему бы не быть последовательными?
- Если стратегия тестирования изменится, не нужно изменять исходный код.
Использование старого тестового кода
Некоторые пользователи могут обнаружить, что у них есть существующий тестовый код, который они хотели бы запустить из unittest, не преобразовывая каждый старый тестовый метод в подкласс TestCase.
По этой причине unittest предоставляет класс FunctionTestCase. Этот подкласс TestCase может использоваться для обертывания существующего тестового метода. Также можно предоставить функции настройки и разборки.
Учитывая следующую тестовую функцию:
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
можно создать эквивалентный тестовый случай следующим образом, с необязательными методами настройки и разборки:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
Примечание
Несмотря на то, что FunctionTestCase можно использовать для быстрого перевода существующей тестовой базы в систему на основе unittest, такой подход не рекомендуется. Потратьте время на создание надлежащих подклассов TestCase, это значительно облегчит будущие рефакторинги тестов.
В некоторых случаях существующие тесты могли быть написаны с использованием модуля doctest. В таком случае, doctest предоставляет класс DocTestSuite , который может автоматически создавать экземпляры unittest.TestSuite из существующих тестов, основанных на doctest.
Пропускание тестов и ожидаемые ошибки
Добавлен в версии 3.1.
Unittest поддерживает пропускание отдельных тестовых методов и целых классов тестов. Кроме того, он поддерживает пометку теста как «ожидаемой ошибки», теста, который сломан и будет давать сбой, но не должен учитываться как сбой в TestResult.
Пропуск теста — это просто использование skip() декоратор или одного из его условных вариантов, вызов TestCase.skipTest() внутри setUp() или тестовом методе или поднятие SkipTest напрямую.
Базовый пропуск выглядит так:
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
def test_maybe_skipped(self):
if not external_resource_available():
self.skipTest("external resource not available")
# test code that depends on the external resource
pass
Это вывод выполнения примера выше в подробном режиме:
test_format (__main__.MyTestCase.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 являются точно одного типа и одним из списком, кортежом, словарем, набором, неизменяемым набором или строкой, или любым типом, который подкласс регистрирует с помощью
addTypeEqualityFunc(), вызывается функция сравнения, специфичная для типа, чтобы сгенерировать более полезное сообщение об ошибке по умолчанию (см. также список методов, специфичных для типа).Изменено в версии 3.1: Добавлена автоматическая вызов функции сравнения, специфичной для типа.
Изменено в версии 3.2:
assertMultiLineEqual()добавлена в качестве функции сравнения типов по умолчанию для сравнения строк.
-
assertNotEqual(first, second, msg=None) -
Проверка, что first и second не равны. Если значения сравниваются как равные, тест завершится сбоем.
-
assertTrue(expr, msg=None) -
assertFalse(expr, msg=None) -
Проверка, что expr истинно (или ложно).
Обратите внимание, что это эквивалентно
bool(expr) is Trueи не эквивалентноexpr is True(используйтеassertIs(expr, True)для последнего). Этот метод также следует избегать, когда доступны более специфичные методы (например,assertEqual(a, b)вместоassertTrue(a == b)), потому что они предоставляют более подробное сообщение об ошибке в случае сбоя.
-
assertIs(first, second, msg=None) -
assertIsNot(first, second, msg=None) -
Проверка, что first и second являются (или не являются) одним и тем же объектом.
Добавлен в версии 3.1.
-
assertIsNone(expr, msg=None) -
assertIsNotNone(expr, msg=None) -
Проверка, что expr является (или не является)
None.Добавлен в версии 3.1.
-
assertIn(member, container, msg=None) -
assertNotIn(member, container, msg=None) -
Проверка, что member находится (или не находится) в container.
Добавлен в версии 3.1.
-
assertIsInstance(obj, cls, msg=None) -
assertNotIsInstance(obj, cls, msg=None) -
Проверка, что obj является (или не является) экземпляром cls (который может быть классом или кортежем классов, как поддерживается
isinstance()). Для проверки точного типа используйтеassertIs(type(obj), cls).Добавлен в версии 3.2.
Также возможно проверить возникновение исключений, предупреждений и сообщений журнала с помощью следующих методов:
Метод
Проверяет, что
Новый в
fun(*args, **kwds)вызывает excfun(*args, **kwds)вызывает exc, и сообщение соответствует регулярному выражению r3.1
fun(*args, **kwds)вызывает warn3.2
fun(*args, **kwds)вызывает warn, и сообщение соответствует регулярному выражению r3.2
Блок
withзаписывает в журнал logger с минимальным уровнем level3.4
-
The with block does not log on -
logger с минимальным уровнем level
3.10
-
assertRaises(exception, callable, *args, **kwds) - assertRaises(exception, *, msg=None)
-
Проверка, что исключение возникает, когда callable вызывается с любыми позиционными или ключевыми аргументами, которые также передаются в
assertRaises(). Тест проходит, если exception возникает, это ошибка, если возникает другое исключение, или тест завершается сбоем, если исключение не возникает. Для захвата любого из группы исключений в exception может передаваться кортеж, содержащий классы исключений.Если заданы только аргументы exception и, возможно, msg, возвращается менеджер контекста, таким образом, код под тестированием может быть записан непосредственно, а не как функция:
with self.assertRaises(SomeException): do_something()При использовании в качестве менеджера контекста
assertRaises()принимает дополнительный ключевой аргумент msg.Менеджер контекста будет хранить пойманный объект исключения в своем атрибуте
exception. Это может быть полезно, если целью является выполнение дополнительных проверок на возникшее исключение:with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3)Изменено в версии 3.1: Добавлена возможность использования
assertRaises()в качестве менеджера контекста.Изменено в версии 3.2: Добавлен атрибут
exception.Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
assertRaisesRegex(exception, regex, callable, *args, **kwds) - assertRaisesRegex(exception, regex, *, msg=None)
-
Подобно
assertRaises(), но также проверяет, что regex соответствует строковому представлению возникшего исключения. regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования сre.search(). Примеры:self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$", int, 'XYZ')или:
with self.assertRaisesRegex(ValueError, 'literal'): int('XYZ')Добавлен в версии 3.1: Добавлен под именем
assertRaisesRegexp.Изменено в версии 3.2: Переименовано в
assertRaisesRegex().Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
-
assertWarns(warning, callable, *args, **kwds) - assertWarns(warning, *, msg=None)
-
Проверка, что при вызове callable с любыми позиционными или именованными аргументами, которые также переданы в
assertWarns(), возникает предупреждение. Тест проходит, если предупреждение warning возникает, и терпит неудачу, если нет. Любое исключение является ошибкой. Для перехвата любого из набора предупреждений можно передать кортеж, содержащий классы предупреждений, как warnings.Если указаны только аргументы warning и, возможно, msg, возвращается менеджер контекста, чтобы код, подлежащий тестированию, мог быть написан внутри, а не в качестве функции:
with self.assertWarns(SomeWarning): do_something()При использовании в качестве менеджера контекста,
assertWarns()принимает дополнительный именованный аргумент msg.Менеджер контекста сохранит перехваченный объект предупреждения в своем
warningатрибуте, а строку исходного кода, которая вызвала предупреждения, вfilenameиlinenoатрибутах. Это может быть полезно, если целью является выполнение дополнительных проверок на пойманное предупреждение:with self.assertWarns(SomeWarning) as cm: do_something() self.assertIn('myfile.py', cm.filename) self.assertEqual(320, cm.lineno)Этот метод работает независимо от фильтров предупреждений, установленных при его вызове.
Добавлен в версии 3.2.
Изменено в версии 3.3: Добавлен именованный аргумент msg при использовании в качестве менеджера контекста.
-
assertWarnsRegex(warning, regex, callable, *args, **kwds) - assertWarnsRegex(warning, regex, *, msg=None)
-
Как и
assertWarns(), но также проверяет, что regex соответствует сообщению сгенерированного предупреждения. regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования сre.search(). Пример:self.assertWarnsRegex(DeprecationWarning, r'legacy_function\(\) is deprecated', legacy_function, 'XYZ')или:
with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'): frobnicate('/etc/passwd')Добавлен в версии 3.2.
Изменено в версии 3.3: Добавлен именованный аргумент msg при использовании в качестве менеджера контекста.
-
assertLogs(logger=None, level=None) -
Менеджер контекста для проверки того, что хотя бы одно сообщение записывается в журнал logger или в одном из его дочерних элементов, по крайней мере, с указанным уровнем level.
Если задан, logger должен быть объектом
logging.Loggerили строкой, содержащей имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения, которые не были заблокированы нераспространяющимся дочерним логгером.Если задан, level должен быть либо числовым уровнем журнала, либо его строковым эквивалентом (например, либо
"ERROR", либоlogging.ERROR). По умолчанию используетсяlogging.INFO.Тест проходит, если хотя бы одно сообщение, выведенное внутри
withблока, соответствует условиям logger и level, в противном случае тест терпит неудачу.Возвращаемый менеджером контекста объект является инструментом записи, который отслеживает совпадающие записи журнала. У него есть два атрибута:
-
records -
Список объектов
logging.LogRecordсоответствующих записей журнала.
-
output -
Список строк, содержащих отформатированный вывод соответствующих сообщений.
Пример:
with self.assertLogs('foo', level='INFO') as cm: logging.getLogger('foo').info('first message') logging.getLogger('foo.bar').error('second message') self.assertEqual(cm.output, ['INFO:foo:first message', 'ERROR:foo.bar:second message'])Добавлен в версии 3.4.
-
-
assertNoLogs(logger=None, level=None) -
Менеджер контекста для проверки того, что в журнал logger или в один из его дочерних элементов не записываются сообщения с уровнем, по крайней мере, level.
Если задан, logger должен быть объектом
logging.Loggerили строкой, содержащей имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения.Если задан, level должен быть либо числовым уровнем журнала, либо его строковым эквивалентом (например, либо
"ERROR", либоlogging.ERROR). По умолчанию используетсяlogging.INFO.В отличие от
assertLogs(), менеджер контекста ничего не возвращает.Добавлен в версии 3.10.
Также существуют другие методы для выполнения более специфических проверок, такие как:
Метод
Проверяет, что
Новый в
round(a-b, 7) == 0round(a-b, 7) != 0a > b3.1
a >= b3.1
a < b3.1
a <= b3.1
r.search(s)3.1
not r.search(s)3.2
a и b содержат одинаковые элементы в одинаковом количестве, независимо от их порядка.
3.2
-
assertAlmostEqual(first, second, places=7, msg=None, delta=None) -
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None) -
Проверка, что first и second примерно (или не примерно) равны, вычисляя разницу, округляя до заданного количества десятичных знаков places (по умолчанию 7) и сравнивая с нулём. Обратите внимание, что эти методы округляют значения до заданного количества десятичных знаков (то есть как функция
round()), а не значащих цифр.Если указан delta вместо places, то разность между first и second должна быть меньше или равна (или больше) delta.
Если заданы оба delta и places, возникает
TypeError.Изменено в версии 3.2:
assertAlmostEqual()автоматически считает объекты, сравниваемые равными, почти равными.assertNotAlmostEqual()автоматически терпит неудачу, если объекты сравниваются равными. Добавлен именованный аргумент delta.
-
-
assertGreater(first, second, msg=None) -
assertGreaterEqual(first, second, msg=None) -
assertLess(first, second, msg=None) -
assertLessEqual(first, second, msg=None) -
Проверка, что первое значение соответственно >, >=, < или <= второго значения в зависимости от имени метода. В противном случае тест завершится ошибкой:
>>> 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 соответствует (или не соответствует) тексту. В случае ошибки сообщение об ошибке будет включать шаблон и текст (или шаблон и часть текста, которая неожиданно соответствовала). regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования с
re.search().Добавлен в версии 3.1: Добавлен под именем
assertRegexpMatches.Изменено в версии 3.2: Метод
assertRegexpMatches()был переименован вassertRegex().Добавлен в версии 3.2:
assertNotRegex().
-
assertCountEqual(first, second, msg=None) -
Проверка, что последовательность первое содержит те же элементы, что и второе, независимо от их порядка. При их несовпадении будет сгенерировано сообщение об ошибке, в котором перечислены различия между последовательностями.
Дубликаты элементов не игнорируются при сравнении первого и второго. Проверяется, имеет ли каждый элемент одинаковое количество в обеих последовательностях. Эквивалентно:
assertEqual(Counter(list(first)), Counter(list(second))), но также работает с последовательностями неизменяемых объектов.Добавлен в версии 3.2.
Метод
assertEqual()передает проверку равенства для объектов одного типа различным методам, специфичным для типа. Эти методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощьюaddTypeEqualityFunc():-
addTypeEqualityFunc(typeobj, function) -
Регистрирует метод, специфичный для типа, вызываемый методом
assertEqual(), для проверки, равны ли два объекта одного и того же типа (не подклассы). function должен принимать два позиционных аргумента и необязательный аргумент msg=None, как иassertEqual(). Он должен вызывать исключениеself.failureException(msg), если обнаруживается неравенство между первыми двумя параметрами — возможно, предоставляя полезную информацию и объяснение неравенств в сообщении об ошибке.Добавлен в версии 3.1.
Список методов, специфичных для типа, которые автоматически используются методом
assertEqual(), представлен в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать эти методы напрямую.Метод
Используется для сравнения
Добавлен в
строки
3.1
последовательности
3.1
списки
3.1
кортежи
3.1
множества или неизменяемые множества
3.1
словари
3.1
-
assertMultiLineEqual(first, second, msg=None) -
Проверка, что многострочная строка первая равна строке вторая. При несовпадении в сообщении об ошибке будет включена разница между двумя строками, выделяющая отличия. Этот метод используется по умолчанию при сравнении строк с помощью
assertEqual().Добавлен в версии 3.1.
-
assertSequenceEqual(first, second, msg=None, seq_type=None) -
Проверка, что две последовательности равны. Если указан seq_type, то первая и вторая должны быть экземплярами 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().Ошибка возникает, если у первого или второго нет метода
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, и добавление имени теста было перенесено в
TextTestResultв Python 3.2.
-
addCleanup(function, /, *args, **kwargs) -
Добавляет функцию, которая будет вызвана после
tearDown()для очистки ресурсов, используемых во время теста. Функции будут вызваны в обратном порядке к порядку добавления (LIFO). Они вызываются с любыми аргументами и ключевыми аргументами, переданными вaddCleanup()при их добавлении.Если
setUp()завершается ошибкой, что означает, чтоtearDown()не вызывается, то любые добавленные функции очистки всё равно будут вызваны.Добавлен в версии 3.1.
-
enterContext(cm) -
Входит в предоставленный менеджер контекста. При успешном завершении, также добавляет его метод
__exit__()как функцию очистки с помощьюaddCleanup()и возвращает результат метода__enter__().Добавлен в версии 3.11.
-
doCleanups() -
Этот метод вызывается безусловно после
tearDown(), или послеsetUp(), еслиsetUp()вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных с помощью
addCleanup(). Если вам нужно, чтобы функции очистки вызывались доtearDown(), то вы можете сами вызватьdoCleanups().doCleanups()извлекает методы со стека функций очистки по одному, поэтому его можно вызвать в любое время.Добавлен в версии 3.1.
-
classmethod addClassCleanup(function, /, *args, **kwargs) -
Добавляет функцию, которая будет вызвана после
tearDownClass()для очистки ресурсов, используемых во время класса теста. Функции будут вызваны в обратном порядке к порядку добавления (LIFO). Они вызываются с любыми аргументами и ключевыми аргументами, переданными вaddClassCleanup()при их добавлении.Если
setUpClass()завершается ошибкой, что означает, чтоtearDownClass()не вызывается, то любые добавленные функции очистки всё равно будут вызваны.Добавлен в версии 3.8.
-
classmethod enterClassContext(cm) -
Входит в предоставленный менеджер контекста. При успешном завершении, также добавляет его метод
__exit__()как функцию очистки с помощьюaddClassCleanup()и возвращает результат метода__enter__().Добавлен в версии 3.11.
-
classmethod doClassCleanups() -
Этот метод вызывается безусловно после
tearDownClass(), или послеsetUpClass(), еслиsetUpClass()вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных с помощью
addClassCleanup(). Если вам нужно, чтобы функции очистки вызывались доtearDownClass(), то вы можете сами вызватьdoClassCleanups().doClassCleanups()извлекает методы со стека функций очистки по одному, поэтому его можно вызвать в любое время.Добавлен в версии 3.8.
-
-
class unittest.IsolatedAsyncioTestCase(methodName='runTest') -
Этот класс предоставляет API, аналогичный
TestCase, и также принимает корутины в качестве тестовых функций.Добавлен в версии 3.8.
-
coroutine asyncSetUp() -
Метод, вызываемый для подготовки тестового фикстура. Он вызывается после
setUp(). Он вызывается непосредственно перед вызовом тестового метода; любое исключение, поднятое этим методом, помимоAssertionErrorилиSkipTest, будет рассматриваться как ошибка, а не как сбой теста. По умолчанию реализация ничего не делает.
-
coroutine asyncTearDown() -
Метод, вызываемый непосредственно после того, как был вызван тестовый метод и результат был записан. Он вызывается перед
tearDown(). Он вызывается даже если тестовый метод поднял исключение, поэтому реализация в подклассах должна быть особенно внимательна к проверке внутреннего состояния. Любое исключение, помимоAssertionErrorилиSkipTest, поднятое этим методом, будет рассматриваться как дополнительная ошибка, а не как сбой теста (тем самым увеличивая общее количество сообщенных ошибок). Этот метод будет вызван только в случае успешного выполненияasyncSetUp(), независимо от результата выполнения тестового метода. По умолчанию реализация ничего не делает.
-
addAsyncCleanup(function, /, *args, **kwargs) -
Этот метод принимает корутину, которая может использоваться как функция очистки.
-
coroutine enterAsyncContext(cm) -
Входит в предоставленный асинхронный менеджер контекста. В случае успеха, также добавляет его метод
__aexit__()как функцию очистки с помощьюaddAsyncCleanup()и возвращает результат метода__aenter__().Добавлен в версии 3.11.
-
run(result=None) -
Создаёт новую событийную петлю для запуска теста, собирая результат в объект
TestResult, переданный как result. Если result опущен илиNone, создаётся временный объект результата (вызывая методdefaultTestResult()) и используется. Объект результата возвращается вызывающей сторонеrun(). В конце теста все задачи в событийной петле отменяются.
Пример, иллюстрирующий порядок:
from unittest import IsolatedAsyncioTestCase events = [] class Test(IsolatedAsyncioTestCase): def setUp(self): events.append("setUp") async def asyncSetUp(self): self._async_connection = await AsyncConnection() events.append("asyncSetUp") async def test_response(self): events.append("test_response") response = await self._async_connection.get("https://example.com") self.assertEqual(response.status_code, 200) self.addAsyncCleanup(self.on_cleanup) def tearDown(self): events.append("tearDown") async def asyncTearDown(self): await self._async_connection.close() events.append("asyncTearDown") async def on_cleanup(self): events.append("cleanup") if __name__ == "__main__": unittest.main()После выполнения теста,
eventsбудет содержать["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]. -
-
class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None) -
Этот класс реализует часть интерфейса
TestCase, которая позволяет тестовому исполнителю управлять тестом, но не предоставляет методы, которые код теста может использовать для проверки и сообщения об ошибках. Это используется для создания тестовых случаев с использованием устаревшего кода тестов, позволяя его интегрировать в тестовый фреймворк на основеunittest.
Группировка тестов
-
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).Если этот атрибут не пустой (значение по умолчанию), все тестовые методы, которые должны быть включены в наборы тестов, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что сопоставление всегда выполняется с помощью
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* methods.
-
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, если были какие-либоunexpectedSuccessesот тестов, помеченных декораторомexpectedFailure().
-
stop() -
Этот метод может быть вызван для сигнализации о том, что набор выполняемых тестов должен быть прерван, установив атрибут
shouldStopвTrue. ОбъектыTestRunnerдолжны учитывать этот флаг и возвращаться без выполнения дополнительных тестов.Например, эта функция используется классом
TextTestRunnerдля остановки фреймворка тестирования, когда пользователь сигнализирует об прерывании с клавиатуры. Интерактивные инструменты, которые предоставляют реализацииTestRunner, могут использовать это аналогичным образом.
Следующие методы класса
TestResultиспользуются для поддержания внутренних структур данных и могут быть расширены в подклассах для поддержки дополнительных требований к отчетности. Это особенно полезно при создании инструментов, которые поддерживают интерактивную отчетность во время выполнения тестов.-
startTest(test) -
Вызывается, когда тестовый случай test собирается быть запущен.
-
stopTest(test) -
Вызывается после того, как тестовый случай test был выполнен, независимо от результата.
-
startTestRun() -
Вызывается один раз перед выполнением любых тестов.
Добавлен в версии 3.1.
-
stopTestRun() -
Вызывается один раз после выполнения всех тестов.
Добавлен в версии 3.1.
-
addError(test, err) -
Вызывается, когда тестовый случай test вызывает непредвиденное исключение. err — кортеж, возвращаемый
sys.exc_info():(type, value, traceback).Стандартная реализация добавляет кортеж
(test, formatted_err)в атрибутerrorsэкземпляра, где formatted_err — отформатированная трассировка стека, полученная из err.
-
addFailure(test, err) -
Вызывается, когда тестовый случай test указывает на ошибку. err — кортеж, возвращаемый
sys.exc_info():(type, value, traceback).Стандартная реализация добавляет кортеж
(test, formatted_err)в атрибутfailuresэкземпляра, где formatted_err — отформатированная трассировка стека, полученная из err.
-
addSuccess(test) -
Вызывается, когда тестовый случай test выполняется успешно.
Стандартная реализация ничего не делает.
-
addSkip(test, reason) -
Вызывается, когда тестовый случай test пропускается. reason — причина пропуска теста.
Стандартная реализация добавляет кортеж
(test, reason)в атрибутskippedэкземпляра.
-
-
addExpectedFailure(test, err) -
Вызывается, когда тестовый случай test завершается ошибкой или сгенерировал исключение, но был помечен декоратором
expectedFailure().По умолчанию реализация добавляет кортеж
(test, formatted_err)в атрибут экземпляраexpectedFailures, где formatted_err — отформатированный traceback, полученный из 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. По умолчанию используетсяTextTestResult, если не предоставленresultclass. Класс результата создаётся со следующими аргументами:stream, descriptions, verbosity
-
run(test) -
Этот метод — основной публичный интерфейс для
TextTestRunner. Этот метод принимает экземплярTestSuiteилиTestCase. Создается экземплярTestResultс помощью вызова_makeResult(), и тесты выполняются, а результаты выводятся в stdout.
-
-
unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None) -
Программа командной строки, которая загружает набор тестов из модуля и выполняет их; это в основном для удобного запуска модулей тестов. Самое простое использование этой функции заключается в добавлении следующей строки в конец скрипта теста:
if __name__ == '__main__': unittest.main()Вы можете запустить тесты с более подробной информацией, передав аргумент verbosity:
if __name__ == '__main__': unittest.main(verbosity=2)Аргумент defaultTest — это имя одного теста или итерируемый набор имён тестов для выполнения, если имена тестов не указаны через argv. Если не указан или
Noneи имена тестов не предоставлены через argv, выполняются все тесты, найденные в модуле.Аргумент 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если опция-Wпередаётся в python (см. Управление предупреждениями), иначе он будет установлен в'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.
Командная опция -c/--catch для unittest, наряду с параметром catchbreak для unittest.main(), обеспечивают более дружелюбную обработку нажатия Ctrl+C во время выполнения теста. При включенном поведении отлова прерывания нажатие Ctrl+C позволит текущему выполняемому тесту завершиться, а запуск теста завершится и сообщит все результаты до этого момента. Второе нажатие Ctrl+C вызовет KeyboardInterrupt обычным способом.
Обработчик сигнала для обработки Ctrl+C пытается сохранить совместимость с кодом или тестами, которые устанавливают собственного обработчика signal.SIGINT. Если обработчик unittest вызывается, но не является установленным обработчиком signal.SIGINT, то есть он был заменен системой под тестированием и делегирован, то он вызывает стандартный обработчик. Это обычно ожидаемое поведение кода, который заменяет установленный обработчик и делегирует ему. Для отдельных тестов, которым требуется отключение обработки Ctrl+C, можно использовать декоратор removeHandler().
Существует несколько вспомогательных функций для авторов фреймворков, чтобы включить функциональность обработки Ctrl+C в рамках тестов.
-
unittest.installHandler() -
Установить обработчик Ctrl+C. При получении
signal.SIGINT(обычно в ответ на нажатие пользователем Ctrl+C) всем зарегистрированным результатам вызываетсяstop().
-
unittest.registerResult(result) -
Зарегистрировать объект
TestResultдля обработки Ctrl+C. Регистрация результата сохраняет слабую ссылку на него, поэтому не препятствует сборке мусора результата.Регистрация объекта
TestResultне имеет побочных эффектов, если обработка Ctrl+C не включена, поэтому фреймворки тестов могут безусловно регистрировать все созданные результаты независимо от того, включена ли обработка.
-
unittest.removeResult(result) -
Удалить зарегистрированный результат. После удаления результата
stop()больше не будет вызываться на этом объекте результата в ответ на Ctrl+C.
-
unittest.removeHandler(function=None) -
При вызове без аргументов эта функция удаляет обработчик Ctrl+C, если он был установлен. Эта функция также может использоваться в качестве декоратора теста для временного удаления обработчика во время выполнения теста:
@unittest.removeHandler def test_signal_handling(self): ...
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/unittest.html