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
Сторонняя платформа модульного тестирования с упрощенным синтаксисом для написания тестов. Например,
assert func(10) == 42
.- The Python Testing Tools Taxonomy
Обширный список инструментов тестирования на Python, включая фреймворки функционального тестирования и библиотеки макетных объектов.
- Testing in Python Mailing List
Группа по интересам для обсуждения тестирования и инструментов тестирования на 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
функции, которых достаточно для удовлетворения многих повседневных потребностей в тестировании. В оставшейся части документации рассматривается полный набор функций из first principles.
Изменено в версии 3.11: Поведение, связанное с возвратом значения из тестового метода (отличного от значения по умолчанию None
), теперь устарело.
Интерфейс командной строки¶
Модуль unittest можно использовать из командной строки для запуска тестов из модулей, классов или даже отдельных методов тестирования:
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method
Вы можете передать список с любой комбинацией имен модулей и полными именами классов или методов.
Тестовые модули также могут быть указаны по пути к файлу:
python -m unittest tests/test_something.py
Это позволяет вам использовать заполнение имени файла оболочки для указания тестового модуля. Указанный файл по-прежнему должен быть доступен для импорта как модуль. Путь преобразуется в имя модуля путем удаления «.py» и преобразования разделителей путей в «.». Если вы хотите запустить тестовый файл, который не может быть импортирован как модуль, вам следует запустить его напрямую.
Вы можете запускать тесты с большей детализацией (более высокой степенью детализации), передав флаг -v:
python -m unittest -v test_module
При выполнении без аргументов запускается Обнаружение теста:
python -m unittest
Для получения списка всех параметров командной строки:
python -m unittest -h
Изменено в версии 3.2: В более ранних версиях можно было запускать только отдельные методы тестирования, а не модули или классы.
Параметры командной строки¶
unittest поддерживает следующие параметры командной строки:
- -b, --buffer¶
Стандартные выходные данные и потоки стандартных ошибок буферизуются во время выполнения теста. Выходные данные, полученные во время прохождения теста, отбрасываются. Выходные данные обычно повторяются при сбое теста или ошибке и добавляются к сообщениям о сбоях.
- -c, --catch¶
Control-C во время выполнения теста ожидает завершения текущего теста и затем сообщает обо всех результатах на данный момент. Второе Control-C вызывает обычное
KeyboardInterrupt
исключение.Функции, обеспечивающие эту функциональность, приведены в разделе 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 поддерживает простое обнаружение тестов. Для обеспечения совместимости с test discovery все тестовые файлы должны быть modules или 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 предупредит вас и завершит работу.
Если вы указываете начальный каталог в качестве имени пакета, а не пути к каталогу, то discover предполагает, что независимо от того, из какого местоположения он импортирует, это то место, которое вы хотели, поэтому вы не получите предупреждение.
Тестовые модули и пакеты могут настраивать загрузку и обнаружение тестов с помощью load_tests protocol.
Изменено в версии 3.4: Обнаружение тестов поддерживает namespace packages для начального каталога. Обратите внимание, что вам также необходимо указать каталог верхнего уровня (например, python -m unittest discover -s root/namespace -t root
).
Изменено в версии 3.11: unittest
отменена поддержка namespace packages в Python 3.11. Начиная с Python 3.7, она была нарушена. Начальный каталог и подкаталоги, содержащие тесты, должны быть обычными пакетами, в которых есть __init__.py
файла.
Каталоги, содержащие start directory, по-прежнему могут быть пакетами пространства имен. В этом случае вам нужно указать start directory в качестве имени пакета, обозначенного пунктиром, и явно указать целевой каталог. Например:
# proj/ <-- current directory
# namespace/
# mypkg/
# __init__.py
# test_mypkg.py
python -m unittest discover -s namespace.mypkg -t .
Организация тестового кода¶
Основными компонентами модульного тестирования являются 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* methods, предоставляемых базовым классом 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. Новый экземпляр тестового примера создается как уникальный тестовый инструментарий, используемый для выполнения каждого отдельного метода тестирования. Таким образом, setUp()
, tearDown()
, и __init__()
будут вызываться один раз за тест.
Рекомендуется использовать реализации тестовых наборов для группировки тестов в соответствии с функциями, которые они тестируют. 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
Это результат выполнения приведенного выше примера в подробном режиме:
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)¶
Безоговорочно пропустите оформленный тест. причина должна содержать описание причины, по которой тест пропускается.
- @unittest.skipIf(condition, reason)¶
Пропустите оформленный тест, если условие истинно.
- @unittest.skipUnless(condition, reason)¶
Пропустите оформленный тест, если только условие не является истинным.
- @unittest.expectedFailure¶
Отметьте тест как ожидаемый сбой или ошибку. Если тест завершился неудачно или возникли ошибки в самой тестовой функции (а не в одном из методов test fixture), это будет считаться успешным. Если тест прошел успешно, это будет считаться неудачным.
- exception unittest.SkipTest(reason)¶
Это исключение создается для пропуска теста.
Обычно вы можете использовать
TestCase.skipTest()
или один из пропускающих декораторов вместо того, чтобы вызывать это напрямую.
Пропущенные тесты не будут содержать setUp()
или tearDown()
. Пропущенные классы не будут содержать setUpClass()
или tearDownClass()
. Пропущенные модули не будут запускаться setUpModule()
или tearDownModule()
.
Различение итераций тестирования с использованием субтестов¶
Добавлено в версии 3.4.
Когда между вашими тестами есть очень небольшие различия, например, в некоторых параметрах, модульный тест позволяет вам различать их в теле метода тестирования с помощью контекстного менеджера 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): ...
Смотрите 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. Если значения не совпадают, тест не будет выполнен.
Кроме того, если first и second имеют один и тот же тип и относятся к list, tuple, dict, set, frozenset или str или любому другому типу, который подкласс регистрирует с помощью
addTypeEqualityFunc()
, будет вызвана функция равенства, зависящая от типа, чтобы сгенерировать более полезное сообщение об ошибке по умолчанию (смотрите также list of type-specific methods).Изменено в версии 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)¶
Проверьте, являются ли первый и второй одним и тем же объектом (или нет).
Добавлено в версии 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)
повышает excfun(*args, **kwds)
вызывает exc, и сообщение соответствует регулярному выражению r3.1
fun(*args, **kwds)
вызывает предупреждение3.2
fun(*args, **kwds)
выдает warn, и сообщение соответствует регулярному выражению r3.2
Блок
with
регистрирует логгер с минимальным уровнем3.4
- Блок
with
не выполняет вход в систему регистратор с минимальным уровнем
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()
, но также проверяет, соответствует ли регулярное выражение строковому представлению вызванного исключения. регулярное выражение может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования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()
, но также проверяет, совпадает ли регулярное выражение с сообщением о срабатывающем предупреждении. регулярное выражение может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования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()
), а не до значащих цифр.Если вместо places указана delta, то разница между first и second должна быть меньше или равна (или больше) delta.
При указании как delta, так и places возникает значение
TypeError
.Изменено в версии 3.2:
assertAlmostEqual()
автоматически учитывает почти равные объекты, которые сравниваются равными.assertNotAlmostEqual()
автоматически завершается ошибкой, если объекты сравниваются равными. Добавлен аргумент ключевого слова delta.
- assertGreater(first, second, msg=None)¶
- assertGreaterEqual(first, second, msg=None)¶
- assertLess(first, second, msg=None)¶
- assertLessEqual(first, second, msg=None)¶
Проверьте, что значение first равно соответственно >, >=, < или <=, чем значение second, в зависимости от названия метода. Если нет, тест завершится неудачей:
>>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4"
Добавлено в версии 3.1.
- assertRegex(text, regex, msg=None)¶
- assertNotRegex(text, regex, msg=None)¶
Проверьте, соответствует ли поиск по регулярному выражению (или не соответствует) тексту. В случае сбоя в сообщении об ошибке будут указаны шаблон и текст (или шаблон и часть текста, которые неожиданно совпали). regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования
re.search()
.Добавлено в версии 3.1: Добавлен под названием
assertRegexpMatches
.Изменено в версии 3.2: Метод
assertRegexpMatches()
был переименован вassertRegex()
.Добавлено в версии 3.2:
assertNotRegex()
.Добавлено в версии 3.5: Имя
assertNotRegexpMatches
является устаревшим псевдонимом дляassertNotRegex()
.
- assertCountEqual(first, second, msg=None)¶
Проверьте, содержит ли последовательность first те же элементы, что и second, независимо от их порядка. Если это не так, будет сгенерировано сообщение об ошибке с указанием различий между последовательностями.
Повторяющиеся элементы не игнорируются при сравнении первого и второго. Это проверяет, имеет ли каждый элемент одинаковое количество в обеих последовательностях. Эквивалентно:
assertEqual(Counter(list(first)), Counter(list(second)))
, но также работает с последовательностями объектов, которые невозможно удалить.Добавлено в версии 3.2.
Метод
assertEqual()
отправляет проверку на равенство для объектов одного типа различным методам, зависящим от типа. Эти методы уже реализованы для большинства встроенных типов, но также возможно зарегистрировать новые методы с помощьюaddTypeEqualityFunc()
:- addTypeEqualityFunc(typeobj, function)¶
Регистрирует специфичный для типа метод, вызываемый
assertEqual()
, чтобы проверить, являются ли два объекта абсолютно одинакового typeobj (не подкласса) одинаковыми. функция должна принимать два позиционных аргумента и третий аргумент ключевого слова msg=None точно так же, как это делаетassertEqual()
. Он должен выдаватьself.failureException(msg)
при обнаружении неравенства между первыми двумя параметрами - возможно, предоставляя полезную информацию и подробно объясняя неравенства в сообщении об ошибке.Добавлено в версии 3.1.
Список методов, зависящих от типа, автоматически используемых
assertEqual()
, представлен в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать эти методы напрямую.Метод
Используется для сравнения
Новое в
струнные
3.1
последовательности
3.1
списки
3.1
кортежи
3.1
наборы или заморозка
3.1
диктанты
3.1
- assertMultiLineEqual(first, second, msg=None)¶
Проверьте, что многострочная строка first равна строке second. Если она не равна, в сообщение об ошибке будет включена разница между двумя строками, подчеркивающая различия. Этот метод используется по умолчанию при сравнении строк с
assertEqual()
.Добавлено в версии 3.1.
- assertSequenceEqual(first, second, msg=None, seq_type=None)¶
Проверяет, что две последовательности равны. Если указан seq_type, то и first, и second должны быть экземплярами seq_type, иначе возникнет ошибка. Если последовательности различаются, создается сообщение об ошибке, которое показывает разницу между ними.
Этот метод не вызывается напрямую
assertEqual()
, но он используется для реализацииassertListEqual()
иassertTupleEqual()
.Добавлено в версии 3.1.
- assertListEqual(first, second, msg=None)¶
- assertTupleEqual(first, second, msg=None)¶
Проверяет, совпадают ли два списка или кортежа. В противном случае создается сообщение об ошибке, в котором отображаются только различия между ними. Ошибка также возникает, если какой-либо из параметров имеет неправильный тип. Эти методы используются по умолчанию при сравнении списков или кортежей с
assertEqual()
.Добавлено в версии 3.1.
- assertSetEqual(first, second, msg=None)¶
Проверяет, равны ли два набора. Если нет, выводится сообщение об ошибке, в котором перечисляются различия между наборами. Этот метод используется по умолчанию при сравнении наборов или замороженных наборов с
assertEqual()
.Завершается ошибкой, если ни в одном из первых или вторых методов нет
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
, пользовательское сообщение заменяет стандартное сообщение.Параметр class можно переопределить в отдельных методах тестирования, присвоив атрибуту экземпляра 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 это было изменено, чтобы добавить название теста к краткому описанию даже при наличии строки документации. Это вызвало проблемы с совместимостью с расширениями unittest, и добавление названия теста было перенесено в
TextTestResult
в Python 3.2.
- addCleanup(function, /, *args, **kwargs)¶
Добавьте функцию, которая будет вызываться после
tearDown()
, для очистки ресурсов, используемых во время тестирования. Функции будут вызываться в порядке, обратном порядку их добавления (LIFO). Они вызываются с любыми аргументами и ключевыми словами, передаваемыми вaddCleanup()
при их добавлении.Если
setUp()
завершается ошибкой, что означает, чтоtearDown()
не вызывается, то все добавленные функции очистки все равно будут вызваны.Добавлено в версии 3.1.
- enterContext(cm)¶
Введите указанный context manager. В случае успеха также добавьте его метод
__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)¶
Введите указанный context manager. В случае успеха также добавьте его метод
__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)¶
Введите указанный asynchronous context manager. В случае успеха также добавьте его метод
__aexit__()
в качестве функции очистки с помощьюaddAsyncCleanup()
и верните результат метода__aenter__()
.Добавлено в версии 3.11.
- run(result=None)¶
Настраивает новый цикл обработки событий для запуска теста, собирая результат в объект
TestResult
, передаваемый как result. Если значение result опущено илиNone
, создается временный объект result (путем вызова методаdefaultTestResult()
) и используется. Объект result возвращается вызывающей стороне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
.
Устаревшие псевдонимы¶
По историческим причинам некоторые из методов TestCase
имели один или несколько псевдонимов, которые в настоящее время устарели. В следующей таблице перечислены правильные имена вместе с их устаревшими псевдонимами:
Название метода
Устаревший псевдоним
Устаревший псевдоним
Равный без сбоев
Равные утверждения
Неудача, равная
Assertне имеет равных значений
Безотказный
утверждать_
Неудача, если
Безотказные подъемы
Безотказный, максимально равный
Утверждайте наибольшие значения
Сбой максимально возможный
Утверждайте, что нет наибольших значений
Assertregexpматчи
Assertnotregexp соответствует
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)¶
Запустите тесты, связанные с этим пакетом, собирая результат в объект test result, передаваемый как result. Обратите внимание, что в отличие от
TestCase.run()
,TestSuite.run()
требуется, чтобы объект result был передан в .
- 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)¶
Возвращает набор всех тестовых примеров, содержащихся в
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)¶
Возвращает набор всех тестовых примеров с заданным спецификатором string.
Спецификатор name - это «пунктирное имя», которое может быть преобразовано либо в модуль, класс тестового примера, тестовый метод в классе тестового примера, экземпляр
TestSuite
, либо в вызываемый объект, который возвращаетTestCase
илиTestSuite
экземпляр. Эти проверки применяются в порядке, указанном здесь; то есть метод в возможном классе тестовых наборов будет выбран как «тестовый метод в классе тестовых наборов», а не как «вызываемый объект».Например, если у вас есть модуль
SampleTests
, содержащийTestCase
-производный классSampleTestCase
с тремя методами тестирования (test_one()
,test_two()
, иtest_three()
), спецификатор'SampleTests.SampleTestCase'
приведет к тому, что этот метод вернет набор, который будет запускать все три метода тестирования. Использование указанного'SampleTests.SampleTestCase.test_two'
приведет к возвращению набора тестов, который будет выполнять только тестовый методtest_two()
. Спецификатор может ссылаться на модули и пакеты, которые не были импортированы; они будут импортированы как побочный эффект.Метод необязательно разрешает имя относительно данного модуля.
Изменено в версии 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
независимо от того, совпадает ли их путь с шаблоном, поскольку невозможно, чтобы имя пакета соответствовало шаблону по умолчанию.Изменено в версии 3.11: start_dir не может быть namespace packages. Он был нарушен с тех пор, как Python 3.7 и Python 3.11 официально удалили его.
Следующие атрибуты
TestLoader
могут быть сконфигурированы либо путем создания подкласса, либо путем присвоения экземпляру:- testMethodPrefix¶
Строка, дающая префикс имен методов, которые будут интерпретироваться как методы тестирования. Значение по умолчанию -
'test'
.Это влияет на
getTestCaseNames()
и все методыloadTestsFrom*
.
- sortTestMethodsUsing¶
Функция, которая будет использоваться для сравнения имен методов при их сортировке в
getTestCaseNames()
и во всех методахloadTestsFrom*
.
- suiteClass¶
Вызываемый объект, который создает набор тестов из списка тестов. Для результирующего объекта не требуется никаких методов. Значением по умолчанию является класс
TestSuite
.Это влияет на все методы
loadTestsFrom*
.
- testNamePatterns¶
Список шаблонов имен тестов с подстановочными знаками в стиле оболочки Unix, которым должны соответствовать методы тестирования, чтобы их можно было включить в наборы тестов (см. параметр
-k
).Если этот атрибут не равен
None
(значение по умолчанию), все методы тестирования, которые будут включены в наборы тестов, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что сопоставления всегда выполняются с использованиемfnmatch.fnmatchcase()
, поэтому, в отличие от шаблонов, передаваемых с помощью опции-k
, простые шаблоны подстрок должны быть преобразованы с использованием подстановочных знаков*
.Это влияет на все методы
loadTestsFrom*
.Добавлено в версии 3.7.
- class unittest.TestResult¶
Этот класс используется для сбора информации о том, какие тесты прошли успешно, а какие - неудачно.
Объект
TestResult
хранит результаты набора тестов. КлассыTestCase
иTestSuite
обеспечивают правильную запись результатов; авторам тестов не нужно беспокоиться о записи результатов тестов.Тестирования построены на
unittest
может потребоваться доступTestResult
объект, возникших в результате выполнения набора тестов для целей отчетности; аTestResult
экземпляр возвращаетсяTestRunner.run()
метод для этой цели.TestResult
экземпляры имеют следующие атрибуты, которые будут представлять интерес при проверке результатов выполнения набора тестов:- errors¶
Список, содержащий 2 кортежа из экземпляров
TestCase
и строк, содержащих отформатированные данные обратной трассировки. Каждый кортеж представляет собой тест, который вызвал непредвиденное исключение.
- failures¶
Список, содержащий 2 кортежа из экземпляров
TestCase
и строк, содержащих отформатированные результаты трассировки. Каждый кортеж представляет собой тест, в котором сбой был явно зафиксирован с помощью assert* methods.
- 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
экземпляр, описывающий субтест.Если значение результат равно
None
, подтест выполнен успешно. В противном случае он завершается ошибкой с исключением, когда результат является кортежем формы, возвращаемой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)¶
Базовая реализация test runner, которая выводит результаты в поток. Если значение stream равно
None
, то в качестве выходного потока используется значение по умолчаниюsys.stderr
. Этот класс имеет несколько настраиваемых параметров, но, по сути, очень прост. Графические приложения, которые запускают наборы тестов, должны предоставлять альтернативные реализации. Такие реализации должны принимать**kwargs
, поскольку интерфейс для создания runners изменяется при добавлении функций в unittest.По умолчанию в этом бегуне отображаются
DeprecationWarning
,PendingDeprecationWarning
,ResourceWarning
иImportWarning
, даже если они равны ignored by default. Предупреждения об устаревании, вызванные deprecated unittest methods, также имеют специальный регистр, и если фильтры предупреждений'default'
или'always'
, они будут отображаться только один раз для каждого модуля, чтобы избежать слишком большого количества предупреждающих сообщений. Это поведение можно переопределить, используя опции Python-Wd
или-Wa
(см. Warning control) и оставив предупреждения вNone
.Изменено в версии 3.2: Добавлен аргумент
warnings
.Изменено в версии 3.2: Поток по умолчанию установлен на
sys.stderr
во время создания экземпляра, а не во время импорта.Изменено в версии 3.5: Добавлен параметр tb_locals.
- _makeResult()¶
Этот метод возвращает экземпляр
TestResult
, используемыйrun()
. Он не предназначен для прямого вызова, но может быть переопределен в подклассах для предоставления пользовательскогоTestResult
._makeResult()
создает экземпляр класса или вызываемого объекта, переданный в конструктореTextTestRunner
в качестве аргументаresultclass
. По умолчанию используется значениеTextTestResult
, если не указано значениеresultclass
. Результирующий класс создается со следующими аргументами:stream, descriptions, verbosity
- run(test)¶
Этот метод является основным открытым интерфейсом для
TextTestRunner
. Этот метод принимает экземплярTestSuite
илиTestCase
.TestResult
создается путем вызова_makeResult()
, запускаются тесты и результаты выводятся в стандартный вывод.
- unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None)¶
Программа командной строки, которая загружает набор тестов из module и запускает их; в первую очередь это делается для удобства выполнения тестовых модулей. Проще всего использовать эту функцию, добавив следующую строку в конце тестового сценария:
if __name__ == '__main__': unittest.main()
Вы можете запускать тесты с более подробной информацией, передав аргумент verbosity:
if __name__ == '__main__': unittest.main(verbosity=2)
Аргумент defaultTest - это либо имя отдельного теста, либо повторяющийся набор имен тестов, которые будут выполняться, если имена тестов не указаны с помощью argv. Если не указано или
None
и имена тестов не указаны через argv, запускаются все тесты, найденные в module.Аргументом argv может быть список параметров, передаваемых программе, первым элементом которого является название программы. Если не указано или
None
, используются значенияsys.argv
.Аргументом TestRunner может быть либо класс 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: Были добавлены параметры детализация, устойчивость к сбоям, перехват, буфер и предупреждения.
Изменено в версии 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
Если обнаружение запущено в каталоге, содержащем пакет, либо из командной строки, либо с помощью вызова 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: Discovery больше не проверяет имена пакетов на соответствие шаблону из-за невозможности соответствия имен пакетов шаблону по умолчанию.
Классовые и модульные приспособления¶
Настройки на уровне классов и модулей реализованы в TestSuite
. Когда набор тестов обнаруживает тест из нового класса, вызывается tearDownClass()
из предыдущего класса (если таковой существует), за которым следует setUpClass()
из нового класса.
Аналогично, если тест выполняется из модуля, отличного от предыдущего, то выполняется tearDownModule
из предыдущего модуля, за которым следует setUpModule
из нового модуля.
После выполнения всех тестов выполняются окончательные tearDownClass
и tearDownModule
.
Обратите внимание, что совместно используемые устройства плохо сочетаются с [потенциальными] функциями, такими как распараллеливание тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.
По умолчанию тесты, созданные загрузчиками тестов unittest, упорядочиваются таким образом, чтобы сгруппировать все тесты из одних и тех же модулей и классов. Это приведет к тому, что setUpClass
setUpModule
(и т.д.) будут вызываться ровно один раз для каждого класса и модуля. Если вы выберете случайный порядок, чтобы тесты из разных модулей и классов располагались рядом друг с другом, то эти общие фиксированные функции могут вызываться несколько раз за один тестовый запуск.
Общие светильники не предназначены для работы с наборами с нестандартным порядком. Для фреймворков, которые не хотят поддерживать общие светильники, все еще существует BaseTestSuite
.
Если во время выполнения одной из функций shared fixture возникают какие-либо исключения, тест сообщается как ошибка. Поскольку нет соответствующего экземпляра теста, для отображения ошибки создается объект _ErrorHolder
(который имеет тот же интерфейс, что и TestCase
). Если вы просто используете стандартный тестовый инструмент unittest, то эта деталь не имеет значения, но если вы являетесь автором фреймворка, это может быть актуально.
Класс настройки и класс демонтажа¶
Они должны быть реализованы как методы класса:
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
, то класс будет сообщен как пропущенный, а не как ошибка.
Модуль настройки и модуль демонтажа¶
Они должны быть реализованы в виде функций:
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)¶
Введите указанный context manager. В случае успеха также добавьте его метод
__exit__()
в качестве функции очистки с помощьюaddModuleCleanup()
и верните результат метода__enter__()
.Добавлено в версии 3.11.
- unittest.doModuleCleanups()¶
Эта функция вызывается безоговорочно после
tearDownModule()
или послеsetUpModule()
, еслиsetUpModule()
вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных с помощью
addModuleCleanup()
. Если вам нужно, чтобы функции очистки вызывались доtearDownModule()
, то вы можете вызватьdoModuleCleanups()
самостоятельно.doModuleCleanups()
извлекает методы из стека функций очистки по одному, чтобы их можно было вызвать в любое время.Добавлено в версии 3.8.
Обработка сигналов¶
Добавлено в версии 3.2.
Параметр командной строки -c/--catch
для модульного тестирования, а также параметр catchbreak
для unittest.main()
обеспечивают более удобное управление control-C во время тестового запуска. При включенном поведении catch-break control-C позволит завершить текущий тест, после чего тестовый запуск завершится и сообщит обо всех результатах на данный момент. Второй control-c выдаст KeyboardInterrupt
обычным способом.
Обработчик сигналов обработки control-c пытается сохранить совместимость с кодом или тестами, которые устанавливают свой собственный обработчик signal.SIGINT
. Если вызывается обработчик unittest
, но он не является установленным обработчиком signal.SIGINT
, т.е. он был заменен тестируемой системой и делегирован ей, то вызывается обработчик по умолчанию. Обычно это ожидаемое поведение кода, который заменяет установленный обработчик и делегирует ему полномочия. Для отдельных тестов, в которых требуется отключить обработку unittest
control-c, можно использовать removeHandler()
декоратор.
Для авторов фреймворка существует несколько полезных функций, позволяющих включить функциональность управления c в тестовых фреймворках.
- unittest.installHandler()¶
Установите средство управления. При получении
signal.SIGINT
(обычно в ответ на нажатие пользователем клавиши control-c) для всех зарегистрированных результатов вызываетсяstop()
.
- unittest.registerResult(result)¶
Зарегистрируйте объект
TestResult
для обработки на языке control-c. При регистрации результата сохраняется слабая ссылка на него, поэтому это не предотвращает сборку мусора в результате.Регистрация объекта
TestResult
не имеет побочных эффектов, если не включена обработка control-c, поэтому тестовые платформы могут безоговорочно регистрировать все результаты, которые они создают, независимо от того, включена обработка или нет.
- unittest.removeResult(result)¶
Удалите зарегистрированный результат. Как только результат будет удален,
stop()
больше не будет вызываться для этого объекта result в ответ на команду control-c.
- unittest.removeHandler(function=None)¶
При вызове без аргументов эта функция удаляет обработчик control-c, если он был установлен. Эту функцию также можно использовать в качестве декоратора теста для временного удаления обработчика во время выполнения теста:
@unittest.removeHandler def test_signal_handling(self): ...