unittest
— Фреймворк для модульного тестирования¶
Исходный код: Lib/unittest/__init__.py.
(Если вы уже знакомы с основными понятиями тестирования, вы можете пропустить пункт the list of assert methods).
Фреймворк модульного тестирования unittest
изначально был вдохновлен JUnit и имеет схожий вкус с основными фреймворками модульного тестирования в других языках. Он поддерживает автоматизацию тестирования, совместное использование кода настройки и отключения тестов, объединение тестов в коллекции и независимость тестов от фреймворка отчетности.
Для достижения этой цели unittest
поддерживает некоторые важные концепции в объектно-ориентированном виде:
- испытательное приспособление
test fixture представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, и любые связанные с этим действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск серверного процесса.
- тестовый пример
test case - это отдельная единица тестирования. Он проверяет наличие конкретной реакции на определенный набор входных данных.
unittest
предоставляет базовый классTestCase
, который можно использовать для создания новых тестовых случаев.- набор тестов
test suite - это коллекция тестовых случаев, наборов тестов или и того, и другого. Он используется для объединения тестов, которые должны выполняться вместе.
- испытательный стенд
test runner - это компонент, который организует выполнение тестов и предоставляет результат пользователю. Выполнитель может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение для указания результатов выполнения тестов.
См.также
- Модуль
doctest
Еще один модуль поддержки тестирования с совершенно другим вкусом.
- Simple Smalltalk Testing: With Patterns
Оригинальная статья Кента Бека о тестировании фреймворков с использованием паттерна, разделяемого
unittest
.- pytest
Сторонний unittest framework с облегченным синтаксисом для написания тестов. Например,
assert func(10) == 42
.- The Python Testing Tools Taxonomy
Обширный список инструментов тестирования на Python, включая фреймворки для функционального тестирования и библиотеки макетных объектов.
- Testing in Python Mailing List
Специальная группа по интересам для обсуждения тестирования и инструментов тестирования на Python.
Сценарий Tools/unittestgui/unittestgui.py
в исходном дистрибутиве Python представляет собой инструмент с графическим интерфейсом для обнаружения и выполнения тестов. Он предназначен в основном для простоты использования новичками в области модульного тестирования. Для производственных сред рекомендуется, чтобы тесты управлялись системой непрерывной интеграции, такой как Buildbot, Jenkins или Travis-CI, или AppVeyor.
Основной пример¶
Модуль unittest
предоставляет богатый набор инструментов для построения и выполнения тестов. Этот раздел демонстрирует, что небольшого подмножества инструментов достаточно для удовлетворения потребностей большинства пользователей.
Вот короткий сценарий для проверки трех строковых методов:
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
unittest.main()
Тест-кейс создается путем подклассификации unittest.TestCase
. Три отдельных теста определяются методами, имена которых начинаются с букв test
. Это соглашение об именовании информирует программу запуска тестов о том, какие методы представляют тесты.
Суть каждого теста заключается в вызове assertEqual()
для проверки ожидаемого результата; assertTrue()
или assertFalse()
для проверки условия; или assertRaises()
для проверки возникновения определенного исключения. Эти методы используются вместо оператора assert
, чтобы программа тестирования могла накапливать все результаты тестирования и создавать отчет.
Методы setUp()
и tearDown()
позволяют определить инструкции, которые будут выполняться до и после каждого метода тестирования. Более подробно они рассматриваются в разделе Организация тестового кода.
В последнем блоке показан простой способ запуска тестов. unittest.main()
предоставляет интерфейс командной строки к тестовому сценарию. При запуске из командной строки вышеприведенный сценарий выдает результат, который выглядит следующим образом:
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
Передача опции -v
в ваш тестовый сценарий даст команду unittest.main()
включить более высокий уровень многословия и выдать следующий результат:
test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
Приведенные выше примеры показывают наиболее часто используемые возможности unittest
, которых достаточно для удовлетворения многих повседневных потребностей тестирования. В остальной части документации полный набор функций рассматривается с первых принципов.
Интерфейс командной строки¶
Модуль unittest можно использовать из командной строки для запуска тестов из модулей, классов или даже отдельных методов тестирования:
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method
Вы можете передать список с любой комбинацией имен модулей и полностью определенных имен классов или методов.
Тестовые модули могут быть указаны также по пути к файлу:
python -m unittest tests/test_something.py
Это позволяет вам использовать завершение имени файла оболочки для указания тестового модуля. Указанный файл должен быть импортируемым в качестве модуля. Путь преобразуется в имя модуля путем удаления „.py“ и преобразования разделителей пути в „.“. Если вы хотите выполнить тестовый файл, который не может быть импортирован как модуль, вам следует выполнить файл напрямую.
Вы можете запускать тесты с большей детализацией (более высокой степенью многословности), передавая флаг -v:
python -m unittest -v test_module
При выполнении без аргументов запускается Тестовое обнаружение:
python -m unittest
Для получения списка всех опций командной строки:
python -m unittest -h
Изменено в версии 3.2: В предыдущих версиях можно было запускать только отдельные методы тестирования, но не модули или классы.
Параметры командной строки¶
unittest поддерживает эти параметры командной строки:
-
-b
,
--buffer
¶
Потоки стандартного вывода и стандартной ошибки буферизируются во время выполнения теста. Вывод при прохождении теста отбрасывается. При провале или ошибке теста вывод повторяется в обычном режиме и добавляется к сообщениям об ошибках.
-
-c
,
--catch
¶
Control-C во время выполнения теста ожидает окончания текущего теста и затем сообщает все результаты на данный момент. Второй Control-C вызывает обычное исключение
KeyboardInterrupt
.Функции, обеспечивающие эту функциональность, см. в Signal Handling.
-
-f
,
--failfast
¶
Остановите выполнение теста при первой ошибке или сбое.
-
-k
¶
Запускать только те тестовые методы и классы, которые соответствуют шаблону или подстроке. Этот параметр можно использовать несколько раз, в этом случае будут включены все тестовые случаи, соответствующие любому из заданных шаблонов.
Шаблоны, содержащие символ подстановки (
*
), сопоставляются с именем теста с помощьюfnmatch.fnmatchcase()
; в противном случае используется простое сопоставление подстрок с учетом регистра.Шаблоны сопоставляются с полным именем метода тестирования, импортированным загрузчиком тестов.
Например,
-k foo
соответствуетfoo_tests.SomeTest.test_something
,bar_tests.SomeTest.test_foo
, но неbar_tests.FooTest.test_something
.
-
--locals
¶
Показывать локальные переменные в трассировках.
Добавлено в версии 3.2: Добавлены опции командной строки -b
, -c
и -f
.
Добавлено в версии 3.5: Опция командной строки --locals
.
Добавлено в версии 3.7: Опция командной строки -k
.
Командная строка также может использоваться для обнаружения тестов, для запуска всех тестов в проекте или только их подмножества.
Тестовое обнаружение¶
Добавлено в версии 3.2.
Unittest поддерживает простое обнаружение тестов. Для совместимости с обнаружением тестов все тестовые файлы должны быть modules или packages (включая namespace packages) импортируемыми из каталога верхнего уровня проекта (это означает, что их имена файлов должны быть допустимыми identifiers).
Обнаружение тестов реализовано в 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
. Имя пакета, которое вы передадите, будет импортировано, и его местоположение в файловой системе будет использовано в качестве начального каталога.
Осторожно
Test discovery загружает тесты путем их импорта. После того, как test discovery нашел все файлы тестов из указанного вами начального каталога, он преобразует пути в имена пакетов для импорта. Например, foo/bar/baz.py
будет импортирован как foo.bar.baz
.
Если пакет установлен глобально, а вы пытаетесь проверить test discovery на другой копии пакета, то импорт может произойти не из того места. Если это произойдет, test discovery предупредит вас и завершит работу.
Если вы предоставите начальный каталог как имя пакета, а не как путь к каталогу, то discover будет считать, что то место, из которого он импортирует, является тем местом, которое вы выбрали, поэтому вы не получите предупреждение.
Тестовые модули и пакеты могут настраивать загрузку и обнаружение тестов с помощью load_tests protocol.
Изменено в версии 3.4: Тестовое обнаружение поддерживает namespace packages для начального каталога. Обратите внимание, что необходимо указать и каталог верхнего уровня (например, python -m unittest discover -s root/namespace -t root
).
Организация тестового кода¶
Основными строительными блоками модульного тестирования являются test cases — отдельные сценарии, которые должны быть заданы и проверены на корректность. В 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
идентифицирует тестовый случай как failure. Любые другие исключения будут рассматриваться как errors.
Тестов может быть много, и их настройка может быть повторяющейся. К счастью, мы можем отказаться от кода настройки, реализовав метод 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()
будет запущен независимо от того, прошел метод тестирования успешно или нет.
Такая рабочая среда для кода тестирования называется test fixture. Новый экземпляр TestCase создается как уникальное тестовое приспособление, используемое для выполнения каждого отдельного метода тестирования. Таким образом, setUp()
, tearDown()
и __init__()
будут вызываться по одному разу на каждый тест.
Рекомендуется использовать реализацию TestCase для группировки тестов в соответствии с проверяемыми ими функциями. unittest
предоставляет механизм для этого: test suite, представленный классом unittest
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()
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
Вот результат выполнения приведенного выше примера в режиме verbose:
test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available'
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'
----------------------------------------------------------------------
Ran 4 tests in 0.005s
OK (skipped=4)
Классы можно пропускать так же, как и методы:
@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
def test_not_run(self):
pass
TestCase.setUp()
может также пропустить тест. Это полезно, когда ресурс, который необходимо установить, недоступен.
Ожидаемые сбои используют декоратор expectedFailure()
.
class ExpectedFailureTestCase(unittest.TestCase):
@unittest.expectedFailure
def test_fail(self):
self.assertEqual(1, 0, "broken")
Легко создать свои собственные декораторы пропуска теста, создав декоратор, который вызывает skip()
на тесте, когда хочет, чтобы он был пропущен. Этот декоратор пропускает тест, если переданный объект не имеет определенного атрибута:
def skipUnlessHasattr(obj, attr):
if hasattr(obj, attr):
return lambda func: func
return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))
Следующие декораторы и исключения реализуют пропуск тестов и ожидаемые сбои:
-
@
unittest.
skip
(reason)¶ Безоговорочно пропустить декорированный тест. Причина должна описывать, почему тест пропускается.
-
@
unittest.
skipIf
(condition, reason)¶ Пропустите украшенный тест, если условие истинно.
-
@
unittest.
skipUnless
(condition, reason)¶ Пропустите тест decorated, если условие не истинно.
-
@
unittest.
expectedFailure
¶ Пометьте тест как ожидаемый провал или ошибку. Если тест терпит неудачу или ошибку в самой тестовой функции (а не в одном из методов test fixture), то он будет считаться успешным. Если тест пройдет, то он будет считаться неудачным.
-
exception
unittest.
SkipTest
(reason)¶ Это исключение возникает, чтобы пропустить тест.
Обычно вы можете использовать
TestCase.skipTest()
или один из декораторов пропуска вместо того, чтобы вызывать это напрямую.
У пропущенных тестов не будет пробега setUp()
или tearDown()
вокруг них. В пропущенных классах не будет выполняться setUpClass()
или tearDownClass()
. В пропущенных модулях не будет выполняться setUpModule()
или tearDownModule()
.
Различение итераций теста с помощью субтестов¶
Добавлено в версии 3.4.
Когда между вашими тестами есть очень небольшие различия, например, некоторые параметры, unittest позволяет различать их внутри тела метода теста с помощью менеджера контекста subTest()
.
Например, следующий тест:
class NumbersTest(unittest.TestCase):
def test_even(self):
"""
Test that numbers between 0 and 5 are all even.
"""
for i in range(0, 6):
with self.subTest(i=i):
self.assertEqual(i % 2, 0)
приведет к следующему результату:
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=3)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=5)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
Без использования подтеста выполнение остановится после первого сбоя, и ошибку будет не так легко диагностировать, поскольку значение i
не будет отображаться:
======================================================================
FAIL: test_even (__main__.NumbersTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
Классы и функции¶
В этом разделе подробно описывается API unittest
.
Тестовые случаи¶
-
class
unittest.
TestCase
(methodName='runTest')¶ Экземпляры класса
TestCase
представляют логические единицы тестирования во вселеннойunittest
. Этот класс предназначен для использования в качестве базового класса, а конкретные тесты реализуются конкретными подклассами. Этот класс реализует интерфейс, необходимый программе запуска тестов, чтобы она могла управлять тестами, и методы, которые тестовый код может использовать для проверки и сообщения о различных видах сбоев.Каждый экземпляр
TestCase
будет выполнять один базовый метод: метод с именем methodName. В большинстве случаев использованияTestCase
вы не будете ни изменять methodName, ни переименовывать метод по умолчаниюrunTest()
.Изменено в версии 3.2:
TestCase
может быть успешно инстанцирован без указания methodName. Это облегчает эксперименты сTestCase
из интерактивного интерпретатора.Экземпляры
TestCase
предоставляют три группы методов: одна группа используется для запуска теста, другая используется реализацией теста для проверки условий и сообщения о сбоях, а также некоторые методы опроса, позволяющие собирать информацию о самом тесте.Методы в первой группе (выполнение теста) следующие:
-
setUp
()¶ Метод, вызываемый для подготовки приспособления для тестирования. Он вызывается непосредственно перед вызовом метода тестирования; кроме
AssertionError
илиSkipTest
, любое исключение, вызванное этим методом, будет рассматриваться как ошибка, а не как сбой теста. Реализация по умолчанию ничего не делает.
-
tearDown
()¶ Метод вызывается сразу после вызова метода тестирования и записи результата. Этот метод вызывается, даже если метод теста вызвал исключение, поэтому реализация в подклассах может потребовать особой осторожности при проверке внутреннего состояния. Любое исключение, отличное от
AssertionError
илиSkipTest
, вызванное этим методом, будет рассматриваться как дополнительная ошибка, а не как сбой теста (таким образом, увеличивая общее количество зарегистрированных ошибок). Этот метод будет вызван только в случае успехаsetUp()
, независимо от результата метода тестирования. Реализация по умолчанию ничего не делает.
-
setUpClass
()¶ Метод класса, вызываемый перед выполнением тестов в отдельном классе.
setUpClass
вызывается с классом в качестве единственного аргумента и должен быть оформлен какclassmethod()
:@classmethod def setUpClass(cls): ...
Более подробную информацию см. в разделе Class and Module Fixtures.
Добавлено в версии 3.2.
-
tearDownClass
()¶ Метод класса, вызываемый после выполнения тестов в отдельном классе.
tearDownClass
вызывается с классом в качестве единственного аргумента и должен быть оформлен какclassmethod()
:@classmethod def tearDownClass(cls): ...
Более подробную информацию см. в разделе Class and Module Fixtures.
Добавлено в версии 3.2.
-
run
(result=None)¶ Выполните тест, собирая результат в объект
TestResult
, переданный в качестве result. Если result опущен илиNone
, создается временный объект result (путем вызова методаdefaultTestResult()
) и используется. Объект результата возвращается вызывающей сторонеrun()
.Того же эффекта можно добиться, просто вызвав экземпляр
TestCase
.Изменено в версии 3.3: Предыдущие версии
run
не возвращали результат. Также как и вызов экземпляра.
-
skipTest
(reason)¶ Вызов этой функции во время метода тестирования или
setUp()
пропускает текущий тест. Для получения дополнительной информации см. раздел Пропуск тестов и ожидаемые неудачи.Добавлено в версии 3.1.
-
subTest
(msg=None, **params)¶ Возвращает контекстный менеджер, который выполняет вложенный блок кода в качестве подтеста. msg и params - это необязательные, произвольные значения, которые отображаются при каждом сбое подтеста, позволяя вам четко их идентифицировать.
Тестовый пример может содержать любое количество объявлений подтестов, и они могут быть произвольно вложены друг в друга.
Для получения дополнительной информации см. раздел Различение итераций теста с помощью субтестов.
Добавлено в версии 3.4.
-
debug
()¶ Выполнить тест без сбора результатов. Это позволяет исключениям, вызванным тестом, передаваться вызывающей стороне, и может использоваться для поддержки запуска тестов под отладчиком.
Класс
TestCase
предоставляет несколько методов assert для проверки и сообщения о сбоях. В следующей таблице перечислены наиболее часто используемые методы (дополнительные методы assert см. в таблицах ниже):Метод
Проверяет, что
Новое в
a == b
a != b
bool(x) is True
bool(x) is False
a is b
3.1
a is not b
3.1
x is None
3.1
x is not None
3.1
a in b
3.1
a not in b
3.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 являются одинаковыми типами и одним из list, tuple, dict, set, frozenset или str или любым типом, который подкласс регистрирует с помощью
addTypeEqualityFunc()
, будет вызвана специфическая для типа функция равенства, чтобы сгенерировать более полезное сообщение об ошибке по умолчанию (см. также list of type-specific methods).Изменено в версии 3.1: Добавлен автоматический вызов специфической для типа функции равенства.
Изменено в версии 3.2:
assertMultiLineEqual()
добавлена в качестве функции равенства типов по умолчанию для сравнения строк.
-
assertNotEqual
(first, second, msg=None)¶ Проверьте, что первое и второе не равны. Если значения равны, тест завершится неудачей.
-
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)¶ Проверьте, что член находится (или не находится) в контейнере.
Добавлено в версии 3.1.
-
assertIsInstance
(obj, cls, msg=None)¶ -
assertNotIsInstance
(obj, cls, msg=None)¶ Проверьте, что obj является (или не является) экземпляром cls (который может быть классом или кортежем классов, как поддерживается
isinstance()
). Чтобы проверить точный тип, используйтеassertIs(type(obj), cls)
.Добавлено в версии 3.2.
Также можно проверить производство исключений, предупреждений и сообщений журнала, используя следующие методы:
Метод
Проверяет, что
Новое в
fun(*args, **kwds)
вызывает exc.fun(*args, **kwds)
вызывает exc и сообщение соответствует regex r3.1
fun(*args, **kwds)
вызывает warn.3.2
fun(*args, **kwds)
вызывает предупреждение warn и сообщение соответствует regex r3.2
Блок
with
регистрирует журнал на logger с минимальным уровнем.3.4
- Блок
with
не входит в систему логгер с минимальным уровнем.
3.10
-
assertRaises
(exception, callable, *args, **kwds)¶ -
assertRaises
(exception, *, msg=None) Проверяет, что при вызове callable с любыми позиционными или ключевыми аргументами, которые также передаются в
assertRaises()
, возникает исключение. Тест проходит, если вызвано exception, является ошибкой, если вызвано другое исключение, или проваливается, если исключение не вызвано. Чтобы перехватить любое из группы исключений, в качестве exception можно передать кортеж, содержащий классы исключений.Если заданы только аргументы exception и, возможно, msg, верните менеджер контекста, чтобы тестируемый код можно было написать inline, а не как функцию:
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, верните менеджер контекста, чтобы тестируемый код можно было написать inline, а не как функцию:
with self.assertWarns(SomeWarning): do_something()
При использовании в качестве менеджера контекста
assertWarns()
принимает дополнительный аргумент в виде ключевого слова msg.Менеджер контекста будет хранить объект пойманного предупреждения в его атрибуте
warning
, а исходную строку, вызвавшую предупреждение, в атрибутахfilename
иlineno
. Это может быть полезно, если предполагается выполнить дополнительные проверки пойманного предупреждения:with self.assertWarns(SomeWarning) as cm: do_something() self.assertIn('myfile.py', cm.filename) self.assertEqual(320, cm.lineno)
Этот метод работает независимо от фильтров предупреждения, установленных на момент его вызова.
Добавлено в версии 3.2.
Изменено в версии 3.3: Добавлен аргумент ключевого слова msg при использовании в качестве менеджера контекста.
-
assertWarnsRegex
(warning, regex, callable, *args, **kwds)¶ -
assertWarnsRegex
(warning, regex, *, msg=None) Аналогично
assertWarns()
, но также проверяет соответствие 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 или в одном из его дочерних элементов зарегистрировано хотя бы одно сообщение с заданным уровнем.
Если задано, logger должен быть объектом
logging.Logger
илиstr
, задающим имя логгера. По умолчанию используется корневой логгер, который будет перехватывать все сообщения, которые не были заблокированы нераспространяющимся нисходящим логгером.Если задано, level должен быть либо числовым уровнем протоколирования, либо его строковым эквивалентом (например,
"ERROR"
илиlogging.ERROR
). По умолчанию используется значениеlogging.INFO
.Тест проходит, если хотя бы одно сообщение, выданное внутри блока
with
, соответствует условиям logger и level, иначе он проваливается.Объект, возвращаемый менеджером контекста, является помощником записи, который отслеживает совпадающие сообщения журнала. Он имеет два атрибута:
-
records
¶ Список
logging.LogRecord
объектов соответствующих сообщений журнала.
Пример:
with self.assertLogs('foo', level='INFO') as cm: logging.getLogger('foo').info('first message') logging.getLogger('foo.bar').error('second message') self.assertEqual(cm.output, ['INFO:foo:first message', 'ERROR:foo.bar:second message'])
Добавлено в версии 3.4.
-
-
assertNoLogs
(logger=None, level=None)¶ Менеджер контекста для проверки того, что на logger или одном из его дочерних элементов не зарегистрировано никаких сообщений, по крайней мере, с заданным уровнем.
Если задано, logger должен быть объектом
logging.Logger
илиstr
, задающим имя регистратора. По умолчанию используется корневой логгер, который будет перехватывать все сообщения.Если задано, level должен быть либо числовым уровнем протоколирования, либо его строковым эквивалентом (например,
"ERROR"
илиlogging.ERROR
). По умолчанию используется значениеlogging.INFO
.В отличие от
assertLogs()
, менеджер контекста ничего не возвращает.Добавлено в версии 3.10.
Существуют и другие методы, используемые для проведения более специфических проверок, например:
Метод
Проверяет, что
Новое в
round(a-b, 7) == 0
round(a-b, 7) != 0
a > b
3.1
a >= b
3.1
a < b
3.1
a <= b
3.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)¶ Проверьте, что первое и второе приблизительно (или не приблизительно) равны, вычислив разность, округлив до заданного числа десятичных разрядов (по умолчанию 7) и сравнив с нулем. Обратите внимание, что эти методы округляют значения до заданного числа десятичных знаков (т.е. как функция
round()
), а не до значительных цифр.Если вместо мест указана дельта, то разница между первым и вторым должна быть меньше или равна (или больше) дельты.
Если предоставить и 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 соответствует (или не соответствует) тексту. В случае неудачи сообщение об ошибке будет включать шаблон и текст (или шаблон и часть текста, которая неожиданно совпала). regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования
re.search()
.Добавлено в версии 3.1: Добавлено под именем
assertRegexpMatches
.Изменено в версии 3.2: Метод
assertRegexpMatches()
был переименован вassertRegex()
.Добавлено в версии 3.2:
assertNotRegex()
.Добавлено в версии 3.5: Имя
assertNotRegexpMatches
является устаревшим псевдонимом дляassertNotRegex()
.
-
assertCountEqual
(first, second, msg=None)¶ Проверьте, что последовательность первая содержит те же элементы, что и вторая, независимо от их порядка. Если это не так, будет выдано сообщение об ошибке с перечислением различий между последовательностями.
Дублирующиеся элементы не игнорируются при сравнении первого и второго. Проверяется, имеет ли каждый элемент одинаковое количество в обеих последовательностях. Эквивалентно:
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
dicts
3.1
-
assertMultiLineEqual
(first, second, msg=None)¶ Проверьте, равна ли многострочная строка первая строке вторая. Если не равна, в сообщение об ошибке будет включена разница между двумя строками, подчеркивающая различия. Этот метод используется по умолчанию при сравнении строк с помощью
assertEqual()
.Добавлено в версии 3.1.
-
assertSequenceEqual
(first, second, msg=None, seq_type=None)¶ Проверяет равенство двух последовательностей. Если задан seq_type, то и first и second должны быть экземплярами seq_type, иначе будет выдан сбой. Если последовательности разные, выдается сообщение об ошибке, в котором указывается разница между ними.
Этот метод не вызывается непосредственно
assertEqual()
, но он используется для реализацииassertListEqual()
иassertTupleEqual()
.Добавлено в версии 3.1.
-
assertListEqual
(first, second, msg=None)¶ -
assertTupleEqual
(first, second, msg=None)¶ Проверяет, равны ли два списка или кортежа. Если нет, то выдается сообщение об ошибке, в котором указываются только различия между ними. Ошибка также выдается, если один из параметров имеет неправильный тип. Эти методы используются по умолчанию при сравнении списков или кортежей с помощью
assertEqual()
.Добавлено в версии 3.1.
-
assertSetEqual
(first, second, msg=None)¶ Проверяет, что два набора равны. Если нет, то строится сообщение об ошибке, в котором перечисляются различия между множествами. Этот метод используется по умолчанию при сравнении множеств или замороженных множеств с помощью
assertEqual()
.Неудача, если у first или second нет метода
set.difference()
.Добавлено в версии 3.1.
-
assertDictEqual
(first, second, msg=None)¶ Проверьте, что два словаря равны. Если нет, то строится сообщение об ошибке, показывающее различия в словарях. Этот метод будет использоваться по умолчанию для сравнения словарей в вызовах
assertEqual()
.Добавлено в версии 3.1.
Наконец,
TestCase
предоставляет следующие методы и атрибуты:-
fail
(msg=None)¶ Сигнализирует о неудаче теста безусловно, с msg или
None
для сообщения об ошибке.
-
failureException
¶ Этот атрибут класса задает исключение, вызванное методом тестирования. Если тестовому фреймворку необходимо использовать специализированное исключение, возможно, несущее дополнительную информацию, он должен подклассифицировать это исключение, чтобы «играть честно» с фреймворком. Начальное значение этого атрибута -
AssertionError
.
-
longMessage
¶ Этот атрибут класса определяет, что произойдет, если пользовательское сообщение о сбое будет передано в качестве аргумента msg вызову assertXYY, который завершился неудачей. По умолчанию используется значение
True
. В этом случае пользовательское сообщение добавляется в конец стандартного сообщения о сбое. Если установлено значениеFalse
, пользовательское сообщение заменяет стандартное.Настройку класса можно переопределить в отдельных методах тестирования, присвоив атрибуту экземпляра self.longMessage значение
True
илиFalse
перед вызовом методов assert.Настройка класса сбрасывается перед каждым тестовым вызовом.
Добавлено в версии 3.1.
-
maxDiff
¶ Этот атрибут контролирует максимальную длину диффов, выводимых методами assert, которые сообщают о диффах при неудаче. По умолчанию он равен 80*8 символов. Этот атрибут влияет на методы assert:
assertSequenceEqual()
(включая все методы сравнения последовательностей, которые делегируются ему),assertDictEqual()
иassertMultiLineEqual()
.Установка
maxDiff
вNone
означает, что максимальной длины диффов не существует.Добавлено в версии 3.2.
Механизмы тестирования могут использовать следующие методы для сбора информации о тесте:
-
countTestCases
()¶ Возвращает количество тестов, представленных данным объектом теста. Для экземпляров
TestCase
это всегда будет1
.
-
defaultTestResult
()¶ Возвращает экземпляр класса результатов тестирования, который должен использоваться для данного класса тестового случая (если методу
run()
не предоставлен другой экземпляр результата).Для экземпляров
TestCase
это всегда будет экземплярTestResult
; подклассыTestCase
должны переопределять его по мере необходимости.
-
id
()¶ Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя метода тестирования, включая имя модуля и класса.
-
shortDescription
()¶ Возвращает описание теста, или
None
, если описание не было предоставлено. Реализация этого метода по умолчанию возвращает первую строку документальной строки метода теста, если она доступна, илиNone
.Изменено в версии 3.1: В версии 3.1 это было изменено, чтобы добавлять имя теста в краткое описание даже при наличии doc-строки. Это вызвало проблемы совместимости с расширениями unittest, и в Python 3.2 добавление имени теста было перенесено в
TextTestResult
.
-
addCleanup
(function, /, *args, **kwargs)¶ Добавьте функцию, которая будет вызываться после
tearDown()
для очистки ресурсов, использованных во время теста. Функции будут вызываться в порядке, обратном порядку их добавления (LIFO). Они вызываются с любыми аргументами и аргументами ключевых слов, переданными вaddCleanup()
при добавлении.Если
setUp()
потерпит неудачу, то естьtearDown()
не будет вызван, то все добавленные функции очистки все равно будут вызваны.Добавлено в версии 3.1.
-
doCleanups
()¶ Этот метод вызывается безусловно после
tearDown()
, или послеsetUp()
, еслиsetUp()
вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных
addCleanup()
. Если вам нужно, чтобы функции очистки вызывались приоритетно кtearDown()
, то вы можете вызватьdoCleanups()
самостоятельно.doCleanups()
выгружает методы из стека функций очистки по одному за раз, поэтому его можно вызвать в любое время.Добавлено в версии 3.1.
-
classmethod
addClassCleanup
(function, /, *args, **kwargs)¶ Добавьте функцию, которая будет вызываться после
tearDownClass()
для очистки ресурсов, использованных во время работы тестового класса. Функции будут вызываться в порядке, обратном порядку их добавления (LIFO). Они вызываются с любыми аргументами и аргументами ключевых слов, переданными вaddClassCleanup()
при их добавлении.Если
setUpClass()
потерпит неудачу, то естьtearDownClass()
не будет вызван, то все добавленные функции очистки все равно будут вызваны.Добавлено в версии 3.8.
-
classmethod
doClassCleanups
()¶ Этот метод вызывается безусловно после
tearDownClass()
, или послеsetUpClass()
, еслиsetUpClass()
вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных
addClassCleanup()
. Если вам нужно, чтобы функции очистки вызывались приоритетно кtearDownClass()
, то вы можете вызватьdoClassCleanups()
самостоятельно.doClassCleanups()
выгружает методы из стека функций очистки по одному за раз, поэтому его можно вызвать в любое время.Добавлено в версии 3.8.
-
-
class
unittest.
IsolatedAsyncioTestCase
(methodName='runTest')¶ Этот класс предоставляет API, аналогичный
TestCase
, и также принимает coroutines в качестве тестовых функций.Добавлено в версии 3.8.
-
coroutine
asyncSetUp
()¶ Метод, вызываемый для подготовки приспособления для тестирования. Вызывается после
setUp()
. Вызывается непосредственно перед вызовом метода тестирования; кромеAssertionError
илиSkipTest
, любое исключение, вызванное этим методом, будет рассматриваться как ошибка, а не как сбой теста. Реализация по умолчанию ничего не делает.
-
coroutine
asyncTearDown
()¶ Метод, вызываемый сразу после вызова метода тестирования и записи результата. Вызывается перед
tearDown()
. Этот метод вызывается, даже если метод проверки вызвал исключение, поэтому реализация в подклассах может потребовать особой осторожности при проверке внутреннего состояния. Любое исключение, кромеAssertionError
илиSkipTest
, вызванное этим методом, будет рассматриваться как дополнительная ошибка, а не как сбой теста (таким образом, увеличивая общее количество сообщаемых ошибок). Этот метод будет вызван только в случае успехаasyncSetUp()
, независимо от результата метода тестирования. Реализация по умолчанию ничего не делает.
-
addAsyncCleanup
(function, /, *args, **kwargs)¶ Этот метод принимает корутину, которая может быть использована в качестве функции очистки.
-
run
(result=None)¶ Устанавливает новый цикл событий для выполнения теста, собирая результат в объект
TestResult
, переданный в качестве result. Если result опущен илиNone
, создается временный объект result (путем вызова метода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"]
.-
coroutine
-
class
unittest.
FunctionTestCase
(testFunc, setUp=None, tearDown=None, description=None)¶ Этот класс реализует часть интерфейса
TestCase
, которая позволяет программе запуска тестов управлять тестом, но не предоставляет методов, которые тестовый код может использовать для проверки и сообщения об ошибках. Он используется для создания тестовых примеров с использованием унаследованного тестового кода, что позволяет интегрировать его в тестовую структуру на основеunittest
.
Утратившие актуальность псевдонимы¶
По историческим причинам некоторые из методов TestCase
имели один или несколько псевдонимов, которые теперь устарели. В следующей таблице перечислены правильные имена вместе с их устаревшими псевдонимами:
Название метода
Утративший силу псевдоним
Утративший силу псевдоним
failUnlessEqual
assertEquals
failIfEqual
assertNotEquals
failUnless
утверждение_
failIf
failUnlessRaises
failUnlessAlmostEqual
assertAlmostEquals
failIfAlmostEqual
assertNotAlmostEquals
assertRegexpMatches
assertNotRegexpMatches
assertRaisesRegexp
Не рекомендуется, начиная с версии 3.1: Псевдонимы fail*, перечисленные во втором столбце, были устаревшими.
Не рекомендуется, начиная с версии 3.2: Псевдонимы assert*, перечисленные в третьем столбце, были устаревшими.
Не рекомендуется, начиная с версии 3.2:
assertRegexpMatches
иassertRaisesRegexp
были переименованы вassertRegex()
иassertRaisesRegex()
.Не рекомендуется, начиная с версии 3.5: Имя
assertNotRegexpMatches
устарело в пользуassertNotRegex()
.
Группировка тестов¶
-
class
unittest.
TestSuite
(tests=())¶ Этот класс представляет собой совокупность отдельных тестовых случаев и тестовых наборов. Класс представляет интерфейс, необходимый программе запуска тестов, чтобы его можно было запускать как любой другой тестовый случай. Запуск экземпляра
TestSuite
аналогичен итерации по набору, выполняя каждый тест по отдельности.Если указано tests, то это должен быть итерабельный список отдельных тестовых случаев или других тестовых наборов, которые будут использоваться для создания набора изначально. Для последующего добавления тестовых случаев и наборов в коллекцию предусмотрены дополнительные методы.
Объекты
TestSuite
ведут себя так же, как объектыTestCase
, за исключением того, что они фактически не реализуют тест. Вместо этого они используются для объединения тестов в группы тестов, которые должны выполняться вместе. Для добавления тестов к экземплярамTestSuite
доступны некоторые дополнительные методы:-
addTests
(tests)¶ Добавьте все тесты из итерабельного набора экземпляров
TestCase
иTestSuite
в этот набор тестов.Это эквивалентно итерации по тестам, вызывая
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
¶ Список нефатальных ошибок, возникших при загрузке тестов. Не сбрасывается загрузчиком в любой момент. Фатальные ошибки сигнализируются соответствующим методом a, вызывающим исключение. Нефатальные ошибки также обозначаются синтетическим тестом, который при запуске выдает исходную ошибку.
Добавлено в версии 3.5.
Объекты
TestLoader
имеют следующие методы:-
loadTestsFromTestCase
(testCaseClass)¶ Возвращает набор всех тестовых случаев, содержащихся в
TestCase
- производномtestCaseClass
.Для каждого метода, названного
getTestCaseNames()
, создается экземпляр тестового случая. По умолчанию это имена методов, начинающиеся сtest
. ЕслиgetTestCaseNames()
не возвращает никаких методов, но реализован методrunTest()
, то вместо него создается один тестовый пример для этого метода.
-
loadTestsFromModule
(module, pattern=None)¶ Возвращает набор всех тестовых случаев, содержащихся в данном модуле. Этот метод ищет в module классы, производные от
TestCase
и создает экземпляр класса для каждого тестового метода, определенного для класса.Примечание
Хотя использование иерархии
TestCase
-производных классов может быть удобным при совместном использовании приспособлений и вспомогательных функций, определение методов тестирования на базовых классах, которые не предназначены для непосредственного инстанцирования, не очень хорошо сочетается с этим методом. Тем не менее, это может быть полезно, когда приспособления различны и определены в подклассах.Если модуль предоставляет функцию
load_tests
, то она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это и есть load_tests protocol. Аргумент pattern передается в качестве третьего аргумента вload_tests
.Изменено в версии 3.2: Добавлена поддержка
load_tests
.Изменено в версии 3.5: Недокументированный и неофициальный аргумент по умолчанию use_load_tests является устаревшим и игнорируется, хотя он все еще принимается для обратной совместимости. Метод также теперь принимает аргумент pattern, который передается в
load_tests
в качестве третьего аргумента.
-
loadTestsFromName
(name, module=None)¶ Возвращает набор всех тестовых случаев, заданных строковым спецификатором.
Спецификатор name - это «точечное имя», которое может разрешаться либо в модуль, либо в класс тестовых примеров, либо в метод тестирования в классе тестовых примеров, либо в экземпляр
TestSuite
, либо в вызываемый объект, который возвращает экземплярTestCase
илиTestSuite
. Эти проверки применяются в порядке, указанном здесь; то есть метод в возможном классе тестового примера будет воспринят как «метод теста в классе тестового примера», а не как «вызываемый объект».Например, если у вас есть модуль
SampleTests
, содержащийTestCase
-производный классSampleTestCase
с тремя тестовыми методами (test_one()
,test_two()
иtest_three()
), спецификатор'SampleTests.SampleTestCase'
заставит этот метод вернуть набор тестов, в котором будут запущены все три тестовых метода. Использование спецификатора'SampleTests.SampleTestCase.test_two'
приведет к тому, что метод вернет набор тестов, в котором будет запущен только методtest_two()
. Спецификатор может ссылаться на модули и пакеты, которые не были импортированы; они будут импортированы как побочный эффект.Метод опционально разрешает name относительно заданного 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, содержащий их. Будут загружены только те тестовые файлы, которые соответствуют шаблону. (Используется сопоставление шаблонов в стиле оболочки). Будут загружены только те имена модулей, которые можно импортировать (т.е. являются допустимыми идентификаторами Python).
Все тестовые модули должны быть импортируемы с верхнего уровня проекта. Если начальный каталог не является каталогом верхнего уровня, то каталог верхнего уровня должен быть указан отдельно.
Если импорт модуля не удался, например, из-за синтаксической ошибки, то это будет записано как одна ошибка, и обнаружение будет продолжено. Если сбой импорта произошел из-за того, что было вызвано предупреждение
SkipTest
, то это будет записано как пропуск, а не ошибка.Если пакет (каталог, содержащий файл с именем
__init__.py
) найден, пакет будет проверен на наличие функцииload_tests
. Если такая функция существует, то она будет вызванаpackage.load_tests(loader, tests, pattern)
. Обнаружение тестов заботится о том, чтобы пакет проверялся на наличие тестов только один раз во время вызова, даже если сама функция load_tests вызываетloader.discover
.Если
load_tests
существует, то discovery нет рекурсии в пакет,load_tests
отвечает за загрузку всех тестов в пакете.Шаблон намеренно не хранится как атрибут загрузчика, чтобы пакеты могли самостоятельно продолжать открытие. top_level_dir сохраняется, поэтому
load_tests
не нужно передавать этот аргумент вloader.discover()
.start_dir может быть как точечным именем модуля, так и каталогом.
Добавлено в версии 3.2.
Изменено в версии 3.4: Модули, которые при импорте выдают
SkipTest
, записываются как пропуски, а не ошибки.Изменено в версии 3.4: start_dir может быть namespace packages.
Изменено в версии 3.4: Пути сортируются перед импортом, чтобы порядок выполнения был одинаковым, даже если порядок в базовой файловой системе не зависит от имени файла.
Изменено в версии 3.5: Найденные пакеты теперь проверяются на наличие
load_tests
независимо от того, соответствует ли их путь шаблону, поскольку невозможно, чтобы имя пакета соответствовало шаблону по умолчанию.
Следующие атрибуты
TestLoader
могут быть настроены либо путем подклассификации, либо назначением на экземпляр:-
testMethodPrefix
¶ Строка, задающая префикс имен методов, которые будут интерпретироваться как методы тестирования. По умолчанию используется значение
'test'
.Это влияет на
getTestCaseNames()
и все методыloadTestsFrom*()
.
-
sortTestMethodsUsing
¶ Функция, используемая для сравнения имен методов при сортировке в
getTestCaseNames()
и всех методовloadTestsFrom*()
.
-
suiteClass
¶ Вызываемый объект, который конструирует набор тестов из списка тестов. Никакие методы на результирующем объекте не нужны. По умолчанию используется класс
TestSuite
.Это влияет на все методы
loadTestsFrom*()
.
-
testNamePatterns
¶ Список шаблонов имен тестов в стиле Unix shell, которым должны соответствовать методы тестирования, чтобы быть включенными в наборы тестов (см. опцию
-v
).Если этот атрибут не равен
None
(по умолчанию), все тестовые методы, включаемые в наборы тестов, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что соответствие всегда выполняется с использованиемfnmatch.fnmatchcase()
, поэтому в отличие от шаблонов, передаваемых в опцию-v
, простые подстрочные шаблоны должны быть преобразованы с использованием*
подстановочных знаков.Это влияет на все методы
loadTestsFrom*()
.Добавлено в версии 3.7.
-
-
class
unittest.
TestResult
¶ Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие - неудачно.
Объект
TestResult
хранит результаты набора тестов. КлассыTestCase
иTestSuite
обеспечивают правильную запись результатов; авторам тестов не нужно беспокоиться о записи результатов тестов.Механизмы тестирования, построенные поверх
unittest
, могут захотеть получить доступ к объектуTestResult
, сгенерированному при выполнении набора тестов, для создания отчетов; для этого методомTestResult
возвращается экземплярTestRunner.run()
.TestResult
экземпляры имеют следующие атрибуты, которые будут интересны при проверке результатов выполнения набора тестов:-
errors
¶ Список, содержащий 2 кортежа экземпляров
TestCase
и строки, содержащие отформатированные трассировки. Каждый кортеж представляет тест, который вызвал неожиданное исключение.
-
failures
¶ Список, содержащий 2 кортежа экземпляров
TestCase
и строки, содержащие отформатированные трассировки. Каждый кортеж представляет тест, в котором сбой был явно сигнализирован с помощью методовTestCase.assert*()
.
-
skipped
¶ Список, содержащий 2 кортежа экземпляров
TestCase
и строки, содержащие причину пропуска теста.Добавлено в версии 3.1.
-
expectedFailures
¶ Список, содержащий 2 кортежа экземпляров
TestCase
и строки, содержащие отформатированные трассировки. Каждый кортеж представляет ожидаемый сбой или ошибку тестового примера.
-
unexpectedSuccesses
¶ Список, содержащий
TestCase
экземпляров, которые были помечены как ожидаемые неудачи, но завершились успешно.
-
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 пропущен. причина - это причина пропуска теста.
Реализация по умолчанию добавляет кортеж
(test, reason)
к атрибуту экземпляраskipped
.
-
addExpectedFailure
(test, err)¶ Вызывается, когда тестовый пример test провалился или ошибся, но был помечен декоратором
expectedFailure()
.Реализация по умолчанию добавляет кортеж
(test, formatted_err)
к атрибутуexpectedFailures
экземпляра, где formatted_err - это форматированный откат, полученный из err.
-
addUnexpectedSuccess
(test)¶ Вызывается, если тестовый пример test был помечен декоратором
expectedFailure()
, но прошел успешно.Реализация по умолчанию добавляет тест к атрибуту
unexpectedSuccesses
экземпляра.
-
addSubTest
(test, subtest, outcome)¶ Вызывается при завершении подтеста. test - это тестовый пример, соответствующий методу тестирования. subtest - пользовательский экземпляр
TestCase
, описывающий подтест.Если outcome равен
None
, подтест прошел успешно. В противном случае он завершился с исключением, где outcome является кортежем формы, возвращаемой командойsys.exc_info()
:(type, value, traceback)
.Реализация по умолчанию ничего не делает, если результат успешный, и записывает неудачи подтеста как обычные неудачи.
Добавлено в версии 3.4.
-
-
class
unittest.
TextTestResult
(stream, descriptions, verbosity)¶ Конкретная реализация
TestResult
, используемаяTextTestRunner
.Добавлено в версии 3.2: Ранее этот класс назывался
_TextTestResult
. Старое имя все еще существует как псевдоним, но оно устарело.
-
unittest.
defaultTestLoader
¶ Экземпляр класса
TestLoader
, предназначенный для совместного использования. Если не требуется настройкаTestLoader
, этот экземпляр можно использовать вместо многократного создания новых экземпляров.
-
class
unittest.
TextTestRunner
(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False)¶ Базовая реализация программы запуска тестов, которая выводит результаты в поток. Если stream равен
None
, то по умолчанию в качестве выходного потока используетсяsys.stderr
. Этот класс имеет несколько настраиваемых параметров, но по сути очень прост. Графические приложения, запускающие тестовые наборы, должны предоставлять альтернативные реализации. Такие реализации должны принимать**kwargs
в качестве интерфейса для построения бегунков, изменяющихся при добавлении функций в unittest.По умолчанию этот бегунок показывает
DeprecationWarning
,PendingDeprecationWarning
,ResourceWarning
иImportWarning
, даже если они ignored by default. Предупреждения об износе, вызванные deprecated unittest methods, также имеют особый случай, и, если фильтры предупреждений'default'
или'always'
, они будут появляться только один раз для каждого модуля, чтобы избежать слишком большого количества предупреждений. Это поведение можно отменить, используя опции Python-Wd
или-Wa
(см. Warning control) и оставив warnings вNone
.Изменено в версии 3.2: Добавлен аргумент
warnings
.Изменено в версии 3.2: Поток по умолчанию устанавливается в
sys.stderr
во время инстанцирования, а не во время импорта.Изменено в версии 3.5: Добавлен параметр tb_locals.
-
_makeResult
()¶ Этот метод возвращает экземпляр
TestResult
, используемыйrun()
. Он не предназначен для прямого вызова, но может быть переопределен в подклассах для обеспечения пользовательскогоTestResult
._makeResult()
инстанцирует класс или вызываемый объект, переданный в конструктореTextTestRunner
в качестве аргументаresultclass
. По умолчанию используетсяTextTestResult
, если не указаноresultclass
. Класс result инстанцируется со следующими аргументами: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, запускаются все тесты, найденные в module.Аргумент argv может представлять собой список опций, передаваемых программе, первым элементом которого является имя программы. Если он не указан или
None
, то используются значения изsys.argv
.Аргумент testRunner может быть либо классом тестового бегуна, либо уже созданным его экземпляром. По умолчанию
main
вызываетsys.exit()
с кодом выхода, указывающим на успех или неудачу выполнения тестов.Аргумент testLoader должен быть экземпляром
TestLoader
и по умолчанию имеет значениеdefaultTestLoader
.main
поддерживает использование из интерактивного интерпретатора путем передачи аргументаexit=False
. Это выводит результат на стандартный вывод без вызоваsys.exit()
:>>> from unittest import main >>> main(module='test_module', exit=False)
Параметры failfast, catchbreak и buffer имеют тот же эффект, что и одноименные command-line options.
Аргумент warnings задает warning filter, который должен использоваться при выполнении тестов. Если он не указан, то останется
None
, если в-W
передана опция python (см. Warning control), иначе будет установлено значение'default'
.Вызов
main
фактически возвращает экземпляр классаTestProgram
. В нем хранится результат выполнения тестов в виде атрибутаresult
.Изменено в версии 3.1: Был добавлен параметр exit.
Изменено в версии 3.2: Добавлены параметры verbosity, failfast, catchbreak, buffer и warnings.
Изменено в версии 3.4: Параметр defaultTest был изменен, чтобы также принимать итерабельность имен тестов.
load_tests Протокол¶
Добавлено в версии 3.2.
Модули или пакеты могут настроить загрузку тестов из них во время обычного запуска тестов или обнаружения тестов, реализовав функцию load_tests
.
Если тестовый модуль определяет load_tests
, он будет вызван TestLoader.loadTestsFromModule()
со следующими аргументами:
load_tests(loader, standard_tests, pattern)
где шаблон передается прямо из loadTestsFromModule
. По умолчанию он равен None
.
Он должен вернуть значение TestSuite
.
loader - это экземпляр TestLoader
, выполняющий загрузку. standard_tests - это тесты, которые будут загружаться по умолчанию из модуля. Обычно модули тестирования хотят только добавлять или удалять тесты из стандартного набора тестов. Третий аргумент используется при загрузке пакетов как часть обнаружения тестов.
Типичная функция load_tests
, которая загружает тесты из определенного набора TestCase
классов, может выглядеть так:
test_cases = (TestCase1, TestCase2, TestCase3)
def load_tests(loader, tests, pattern):
suite = TestSuite()
for test_class in test_cases:
tests = loader.loadTestsFromTestCase(test_class)
suite.addTests(tests)
return suite
Если discovery запускается в каталоге, содержащем пакет, либо из командной строки, либо вызовом TestLoader.discover()
, то пакет __init__.py
будет проверен на наличие load_tests
. Если такой функции не существует, discovery выполнит поиск в пакете, как если бы это был просто другой каталог. В противном случае обнаружение тестов пакета будет возложено на функцию 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: Discovery больше не проверяет имена пакетов на соответствие шаблону из-за невозможности совпадения имен пакетов с шаблоном по умолчанию.
Приспособления для классов и модулей¶
Фиксы на уровне классов и модулей реализованы в TestSuite
. Когда набор тестов встречает тест из нового класса, то вызывается tearDownClass()
из предыдущего класса (если он есть), а затем setUpClass()
из нового класса.
Аналогично, если тест из другого модуля, чем предыдущий тест, то запускается tearDownModule
из предыдущего модуля, а затем setUpModule
из нового модуля.
После выполнения всех тестов запускаются финальные tearDownClass
и tearDownModule
.
Обратите внимание, что общие фикстуры плохо сочетаются с такими [потенциальными] возможностями, как распараллеливание тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.
Упорядочивание тестов, создаваемых загрузчиками тестов unittest, по умолчанию заключается в том, чтобы сгруппировать все тесты из одних и тех же модулей и классов вместе. Это приведет к тому, что setUpClass
/ setUpModule
(и т.д.) будут вызываться ровно один раз для каждого класса и модуля. Если вы измените порядок, чтобы тесты из разных модулей и классов располагались рядом друг с другом, то эти общие функции приспособления могут быть вызваны несколько раз за один прогон теста.
Общие фикстуры не предназначены для работы с наборами с нестандартным упорядочиванием. Для фреймворков, которые не хотят поддерживать общие приспособления, по-прежнему существует BaseTestSuite
.
Если во время выполнения одной из общих функций приспособления возникают какие-либо исключения, тест сообщается как ошибка. Поскольку нет соответствующего экземпляра теста, создается объект _ErrorHolder
(который имеет тот же интерфейс, что и TestCase
) для представления ошибки. Если вы просто используете стандартную программу запуска тестов unittest, то эта деталь не имеет значения, но если вы являетесь автором фреймворка, то она может иметь значение.
setUpClass и tearDownClass¶
Они должны быть реализованы как методы класса:
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()
Если вы хотите, чтобы вызывались setUpClass
и tearDownClass
на базовых классах, то вы должны вызвать их сами. Реализации в TestCase
являются пустыми.
Если во время setUpClass
возникает исключение, то тесты в классе не выполняются, а tearDownClass
не запускается. У пропущенных классов не будут выполняться setUpClass
или tearDownClass
. Если исключение является исключением SkipTest
, то класс будет сообщен как пропущенный, а не как ошибка.
setUpModule и tearDownModule¶
Они должны быть реализованы как функции:
def setUpModule():
createConnection()
def tearDownModule():
closeConnection()
Если в setUpModule
возникло исключение, то ни один из тестов модуля не будет выполнен, а tearDownModule
не будет выполнен. Если исключение является исключением SkipTest
, то модуль будет сообщен как пропущенный, а не как ошибка.
Чтобы добавить код очистки, который должен быть выполнен даже в случае исключения, используйте addModuleCleanup
:
-
unittest.
addModuleCleanup
(function, /, *args, **kwargs)¶ Добавьте функцию, которая будет вызываться после
tearDownModule()
для очистки ресурсов, использованных во время работы тестового класса. Функции будут вызываться в порядке, обратном порядку их добавления (LIFO). Они вызываются с любыми аргументами и аргументами ключевых слов, переданными вaddModuleCleanup()
при их добавлении.Если
setUpModule()
потерпит неудачу, то естьtearDownModule()
не будет вызван, то все добавленные функции очистки все равно будут вызваны.Добавлено в версии 3.8.
-
unittest.
doModuleCleanups
()¶ Эта функция вызывается безусловно после
tearDownModule()
, или послеsetUpModule()
, еслиsetUpModule()
вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных
addModuleCleanup()
. Если вам нужно, чтобы функции очистки вызывались приоритетно кtearDownModule()
, то вы можете вызватьdoModuleCleanups()
самостоятельно.doModuleCleanups()
выгружает методы из стека функций очистки по одному за раз, поэтому его можно вызвать в любое время.Добавлено в версии 3.8.
Обработка сигналов¶
Добавлено в версии 3.2.
Опция командной строки -c/--catch
для unittest, а также параметр catchbreak
для unittest.main()
обеспечивают более дружественное обращение с control-C во время выполнения теста. При включенном поведении catch break control-C позволит завершить текущий тест, после чего тест завершится и сообщит обо всех полученных результатах. Повторное нажатие control-C вызовет ошибку KeyboardInterrupt
обычным способом.
Обработчик сигналов control-c пытается сохранить совместимость с кодом или тестами, которые устанавливают свой собственный обработчик signal.SIGINT
. Если вызывается обработчик unittest
, но он не является установленным обработчиком signal.SIGINT
, т.е. он был заменен тестируемой системой и делегирован ей, то вызывается обработчик по умолчанию. Обычно это будет ожидаемым поведением кода, который заменяет установленный обработчик и делегирует ему полномочия. Для отдельных тестов, в которых требуется отключить обработку unittest
control-c, можно использовать декоратор removeHandler()
.
Существует несколько полезных функций для авторов фреймворков, позволяющих включить функциональность обработки control-c в тестовые фреймворки.
-
unittest.
installHandler
()¶ Установите обработчик control-c. При получении
signal.SIGINT
(обычно в ответ на нажатие пользователем кнопки control-c) у всех зарегистрированных результатов вызываетсяstop()
.
-
unittest.
registerResult
(result)¶ Зарегистрируйте объект
TestResult
для обработки контрола-c. Регистрация результата хранит слабую ссылку на него, поэтому она не предотвращает сборку результата в мусор.Регистрация объекта
TestResult
не имеет побочных эффектов, если обработка control-c не включена, поэтому тестовые системы могут безоговорочно регистрировать все создаваемые ими результаты независимо от того, включена обработка или нет.
-
unittest.
removeResult
(result)¶ Удаление зарегистрированного результата. Если результат был удален, то
stop()
больше не будет вызываться на этом объекте результата в ответ на команду control-c.
-
unittest.
removeHandler
(function=None)¶ При вызове без аргументов эта функция удаляет обработчик control-c, если он был установлен. Эта функция также может использоваться в качестве декоратора теста для временного удаления обработчика на время выполнения теста:
@unittest.removeHandler def test_signal_handling(self): ...