unittest
— Фреймворк модульного тестирования¶
(Если вы уже знакомы с основными концепциями тестирования, вы можете перейти к перечню методов утверждения.)
Фреймворк модульного тестирования unittest
изначально был вдохновлён
JUnit и очень походит на основные фреймворки модульного тестирования на
других языках. Он поддерживает автоматизацию тестирования, совместное
использование кода настройки и выключения для тестов, объединение тестов в
коллекции и независимость тестов от фреймворков отчётности.
Для этого unittest
поддерживает некоторые важные концепции
объектно-ориентированным способом:
- тестовая фикстура
- тестовая фикстура представляет собой подготовку, необходимую для выполнения одного или нескольких тестов и любые связанные с ними действия по очистке. Это может быть создание временных или прокси баз данных, каталогов или запуск серверного процесса.
- тестовый случай
- тестовый случай — это отдельная единица тестирования. Он проверяет наличие определённого
ответа на определённый множество входных данных.
unittest
предоставляет базовый классTestCase
, который можно использовать для создания новых тестовых случаев. - тестовый комплект
- тестовый комплект — это множество тестовых случаев, наборов тестов или и того, и другого. Он используется для агрегирования выполняемых вместе тестов.
- запускальщик теста
- запускальщик теста — это компонент, управляющий выполнением тестов и предоставляет результат пользователю. Запускальщик может использовать графический интерфейс текстовый интерфейс или возвращает специальное значение для отображения результатов выполнение тестов.
См.также
- Модуль
doctest
- Ещё один модуль поддержки тестирования с совсем другим подходом.
- Простое тестирование в Smalltalk: с помощью шаблонов
- Оригинальная статья Кента Бека о тестовых фреймворках с использованием
шаблона, разработанного
unittest
. - pytest
- Сторонняя среда unittest с облегчённым синтаксисом для написания тестов.
Например,
assert func(10) == 42
. - Таксономия инструментов тестирования Python
- Обширный список инструментов тестирования Python, включая фреймворки функционального тестирования и библиотеки объектов мок.
- Тестирование в списке рассылки Python
- Специальная группа для обсуждения тестирования и инструментов тестирования в 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'])
# проверить, что s.split не работает, если разделитель не
# является строкой
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
.См. Обработка сигналов для получения информации о функциях, реализующих эту функциональность.
-
-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 поддерживает простое обнаружение тестов. Для совместимости с тестовым обнаружением все тестовые файлы должны быть модулями или пакетами (включая пакет пространства имён), которые можно импортировать из каталога верхнего уровня проекта (это означает, что их имена файлов должны быть действительными идентификаторами).
Обнаружение тестов реализовано в TestLoader.discover()
, но также может
использоваться из командной строки. Основное использование командной строки:
cd project_directory
python -m unittest discover
Примечание
В качестве ярлыка python -m unittest
эквивалентен python -m unittest
discover
. Если вы хотите передать аргументы для проверки обнаружения,
подкоманда discover
должна использоваться явно.
У подкоманды discover
следующие параметры:
-
-v
,
--verbose
¶
Подробный вывод
-
-s
,
--start-directory
directory
¶ Каталог для запуска обнаружения (по умолчанию
.
)
-
-p
,
--pattern
pattern
¶ Шаблон для соответствия тестовым файлам (по умолчанию
test*.py
)
-
-t
,
--top-level-directory
directory
¶ Каталог верхнего уровня проекта (по умолчанию это начальный каталог)
Параметры -s
, -p
и -t
могут быть переданы как
позиционные аргументы в указанном порядке. Следующие две командные строки
эквивалентны:
python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"
Помимо пути, в качестве начального каталога можно передать имя пакета, например
myproject.subpackage.test
. Указанное вами имя пакета будет затем
импортировано, и его расположение в файловой системе будет использоваться в
качестве начального каталога.
Осторожно
Обнаружение тестов загружает тесты, импортируя их. После нахождения
всех тестовых файлов из указанного вами начального каталога,
обнаружение тестов преобразует пути в имена пакетов для импорта.
Например, foo/bar/baz.py
будет импортирован как foo.bar.baz
.
Если у вас есть пакет, установленный глобально, и вы пытаетесь выполнить тестовое обнаружение на другой копии пакета, то импорт может происходить не из того места. Если это произойдёт, обнаружение тестов предупредит вас и выйдет.
Если вы укажете начальный каталог в качестве имени пакета, а не пути к каталогу, то обнаружение предполагает, что любое расположение, из которого он импортирует, является вашим предполагаемым расположением, поэтому вы не получите предупреждение.
Модули и пакеты тестирования могут настраивать загрузку и обнаружение тестов с помощью протокола load_tests.
Изменено в версии 3.4: Обнаружение тестов поддерживает пакеты пространства имён.
Организация тестового кода¶
Основными строительными блоками модульного тестирования являются отдельные
сценарии тестовых случаев, которые необходимо настроить и проверить на
правильность. В unittest
тестовые случаи представлены экземплярами
unittest.TestCase
. Чтобы создать свои тестовые случаи, вы
должны написать подклассы TestCase
или использовать FunctionTestCase
.
Код тестирования экземпляра TestCase
должен быть полностью автономным,
чтобы его можно было запускать изолированно или в произвольной комбинации с
любым количеством других тестовых примеров.
Простейший подкласс TestCase
просто реализует метод тестирования (т.
е. метод, имя которого начинается с test
) для выполнения определённого кода
тестирования:
import unittest
class DefaultWidgetSizeTestCase(unittest.TestCase):
def test_default_widget_size(self):
widget = Widget('The widget')
self.assertEqual(widget.size(), (50, 50))
Обратите внимание, что для проверки мы используем один из методов
assert*()
, предоставляемых базовым классом TestCase
. Если тест
не пройден, вызывается исключение с пояснительным сообщением, и unittest
идентифицирует тестовый пример как отказ. Любые другие исключения
будут рассматриваться как ошибки.
Тестов может быть множество, и их настройка может повторяться. К счастью, мы
можем выделить код настройки, реализовав метод под названием
setUp()
, который среда тестирования будет автоматически
вызывать для каждого отдельного запускаемого нами теста
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def test_default_widget_size(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
def test_widget_resize(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
Примечание
Порядок, в котором будут выполняться различные тесты, определяется путем сортировки имён тестовых методов относительно встроенного порядка для строк.
Если метод setUp()
вызывает исключение во время выполнения
теста, платформа сочтет, что в тесте произошла ошибка, и метод тестирования не
будет выполнен.
Точно так же мы можем предоставить метод tearDown()
, который
убирается после запуска метода тестирования:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
Если setUp()
завершился успешно, tearDown()
будет запущен независимо от того, был ли метод проверки успешным или нет.
Такая рабочая среда для кода тестирования называется тестовой фикстурой. Новый
экземпляр TestCase создаётся как уникальное приспособление для тестирования,
используемое для выполнения каждого отдельного метода тестирования. Таким
образом, setUp()
, tearDown()
и
__init__()
будут вызываться один раз за тест.
Рекомендуется использовать реализации TestCase для группировки тестов в
соответствии с тестируемыми функциями. unittest
предоставляет механизм
для этого: тестовый комплект, представленный классом TestSuite
unittest
. В большинстве случаев вызов unittest.main()
поступит
правильно: соберет за вас все тестовые примеры модуля и выполнит их.
Однако, если вы хотите настроить сборку своего набора тестов, вы можете сделать это самостоятельно:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_widget_size'))
suite.addTest(WidgetTestCase('test_widget_resize'))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
Вы можете разместить определения тестовых примеров и наборов тестов в тех же
модулях, что и код, который они должны тестировать (например,
widget.py
), но есть несколько преимуществ размещения тестового кода в
отдельном модуле, например test_widget.py
:
- Тестовый модуль можно запустить автономно из командной строки.
- Тестовый код легче отделить от поставляемого кода.
- Меньше соблазна изменить тестовый код, чтобы он соответствовал тестируемому коду без уважительной причины.
- Тестовый код следует изменять гораздо реже, чем код, который он тестирует.
- Протестированный код легче подвергнуть рефакторингу.
- Тесты для модулей, написанных на C, в любом случае должны быть в отдельных модулях, так почему бы не быть последовательными?
- При изменении стратегии тестирования нет необходимости изменять исходный код.
Повторное использование старого тестового кода¶
Некоторые пользователи обнаружат, что у них есть существующий тестовый код,
который они хотели бы запустить из unittest
, без преобразования каждой
старой тестовой функции в подкласс TestCase
.
По этой причине unittest
предоставляет класс FunctionTestCase
.
Данный подкласс TestCase
можно использовать для обертывания
существующей тестовой функции. Также могут быть предусмотрены функции настройки
и демонтажа.
Учитывая следующую тестовую функцию:
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
можно создать эквивалентный экземпляр тестового примера следующим образом, с дополнительными методами настройки и удаления:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
Примечание
Несмотря на то, что FunctionTestCase
можно использовать для
быстрого преобразования существующей тестовой базы в систему на основе
unittest
, данный подход не рекомендуется. Если вы потратите время
на настройку правильных подклассов TestCase
, это значительно
упростит будущий рефакторинг тестов.
В некоторых случаях существующие тесты могли быть написаны с использованием
модуля doctest
. Если это так, doctest
предоставляет класс
DocTestSuite
, который может автоматически создавать экземпляры
unittest.TestSuite
из существующих тестов на основе doctest
.
Пропуск тестов и ожидаемые сбои¶
Добавлено в версии 3.1.
Unittest поддерживает пропуск отдельных методов тестирования и даже целых
классов тестов. Кроме того, он поддерживает пометку теста как «ожидаемого
сбоя», теста, который не удался, но не должен считаться неудачным на
TestResult
.
Пропуск теста — это просто вопрос использования skip()
декоратора или одного из его условных вариантов, вызова
TestCase.skipTest()
в рамках setUp()
, а также метода
тестирования, или прямого вызова SkipTest
.
Базовый пропуск выглядит так
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Тесты, работающие только для определенной версии библиотеки.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# код тестирования для Windows
pass
def test_maybe_skipped(self):
if not external_resource_available():
self.skipTest("external resource not available")
# тестовый код, зависящий от внешнего ресурса
pass
Это результат выполнения приведенного выше примера в подробном режиме:
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)¶ Безоговорочно пропустить декорированный тест. reason должен описать, почему тест пропускается.
-
@
unittest.
skipIf
(condition, reason)¶ Пропустить декорированный тест, если condition верен.
-
@
unittest.
skipUnless
(condition, reason)¶ Пропустить декорированный тест, если condition не верен.
-
@
unittest.
expectedFailure
¶ Отметить тест как ожидаемый сбой или ошибку. Если тест не прошёл или возникли ошибки, он будет считаться успешным. Если тест пройден, это будет считаться неудачным.
-
exception
unittest.
SkipTest
(reason)¶ Вызывается исключение, чтобы пропустить тест.
Обычно вы можете использовать
TestCase.skipTest()
или один из пропускающих декораторов вместо того, чтобы напрямую вызывать данное исключение.
Пропущенные тесты не будут содержать setUp()
или
tearDown()
. Пропущенные классы не будут запускать
setUpClass()
или tearDownClass()
. Пропущенные
модули не будут запускать setUpModule()
или tearDownModule()
.
Различение итераций теста с помощью подтестов¶
Добавлено в версии 3.4.
Когда между вашими тестами есть очень небольшие различия, например некоторые
параметры, unittest позволяет вам различать их внутри тела метода тестирования
с помощью менеджера контекста subTest()
.
Например, следующий тест:
class NumbersTest(unittest.TestCase):
def test_even(self):
"""
Проверить, все ли числа от 0 до 5 четны.
"""
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): ...
См. Фикстуры классов и модулей для получения более подробной информации.
Добавлено в версии 3.2.
-
tearDownClass
()¶ Метод класса, вызываемый после выполнения тестов в отдельном классе.
tearDownClass
вызывается с классом в качестве единственного аргумента и должен быть декорирован какclassmethod()
:@classmethod def tearDownClass(cls): ...
См. Фикстуры классов и модулей для получения более подробной информации.
Добавлено в версии 3.2.
-
run
(result=None)¶ Запустить тест, собрав результат в объект
TestResult
, переданный как result. Если result пропущен илиNone
, создаётся и используется временный объект результата (путем вызова методаdefaultTestResult()
). Объект результата возвращается вызывающей сторонеrun()
.Тот же эффект можно получить, просто вызвав экземпляр
TestCase
.Изменено в версии 3.3: Предыдущие версии
run
не вернули результат. И при вызове экземпляра тоже.
-
skipTest
(reason)¶ Вызов этого метода во время теста или
setUp()
пропускает текущий тест. См. Пропуск тестов и ожидаемые сбои для получения дополнительной информации.Добавлено в версии 3.1.
-
subTest
(msg=None, **params)¶ Возвращает менеджер контекста, который выполняет вложенный блок кода в качестве подтеста. msg и params являются необязательными, произвольными значениями, которые отображаются при сбое подтеста, что позволяет четко их идентифицировать.
Тестовый пример может содержать любое количество объявлений подтестов, и у них может быть произвольная вложенность.
См. Различение итераций теста с помощью подтестов для получения дополнительной информации.
Добавлено в версии 3.4.
-
debug
()¶ Запустить тест без получения результата. Он позволяет распространять исключения, вызванные тестом, на вызывающую программу и может использоваться для поддержки выполнения тестов в отладчике.
Класс
TestCase
предоставляет несколько методов assert для проверки и сообщения о сбоях. В следующей таблице перечислены наиболее часто используемые методы (дополнительные методы assert см. в таблицах ниже):Метод Что проверяет Новое в assertEqual(a, b)
a == b
assertNotEqual(a, b)
a != b
assertTrue(x)
bool(x) is True
assertFalse(x)
bool(x) is False
assertIs(a, b)
a is b
3.1 assertIsNot(a, b)
a is not b
3.1 assertIsNone(x)
x is None
3.1 assertIsNotNone(x)
x is not None
3.1 assertIn(a, b)
a in b
3.1 assertNotIn(a, b)
a not in b
3.1 assertIsInstance(a, b)
isinstance(a, b)
3.2 assertNotIsInstance(a, b)
not isinstance(a, b)
3.2 Все методы assert принимают аргумент msg, который, если он указан, используется в качестве сообщения об ошибке при сбое (см. также
longMessage
). Обратите внимание, что ключевой аргумент msg может быть передан вassertRaises()
,assertRaisesRegex()
,assertWarns()
,assertWarnsRegex()
, только если они используются в качестве менеджера контекста.-
assertEqual
(first, second, msg=None)¶ Убедиться, что first и second равны. Если значения не совпадают, тест не пройден.
Кроме того, если first и second являются одним и тем же типом и одним из list, tuple, dict, set, frozenset или str или любого типа, который подкласс регистрирует с помощью
addTypeEqualityFunc()
, функция равенства для типа будет вызвана, чтобы сгенерировать более полезное сообщение об ошибке по умолчанию (см. также список методов, зависящих от типа).Изменено в версии 3.1: Добавлен автоматический вызов функции равенства типов.
Изменено в версии 3.2:
assertMultiLineEqual()
добавлен в качестве функции равенства типов по умолчанию для сравнения строк.
-
assertNotEqual
(first, second, msg=None)¶ Проверяет, что first и second не равны. Если значения действительно совпадают, тест не пройден.
-
assertTrue
(expr, msg=None)¶ -
assertFalse
(expr, msg=None)¶ Проверяет, что expr истинно (или ложно).
Обратите внимание, что это эквивалентно
bool(expr) is True
, а неexpr is True
(для последнего используйтеassertIs(expr, True)
). Данный метод также следует избегать, когда доступны более специфические методы (например,assertEqual(a, b)
вместоassertTrue(a == b)
), потому что они обеспечивают лучшее сообщение об ошибке в случае сбоя.
-
assertIs
(first, second, msg=None)¶ -
assertIsNot
(first, second, msg=None)¶ Проверяет, что first и second являются (или не являются) одним и тем же объектом.
Добавлено в версии 3.1.
-
assertIsNone
(expr, msg=None)¶ -
assertIsNotNone
(expr, msg=None)¶ Убедиться, что expr является (или не является)
None
.Добавлено в версии 3.1.
-
assertIn
(member, container, msg=None)¶ -
assertNotIn
(member, container, msg=None)¶ Убедиться, что member находится (или нет) в container.
Добавлено в версии 3.1.
-
assertIsInstance
(obj, cls, msg=None)¶ -
assertNotIsInstance
(obj, cls, msg=None)¶ Проверить, что obj является (или не является) экземпляром cls (который может быть классом или кортежем классов, как поддерживается
isinstance()
). Чтобы проверить точный тип, используйтеassertIs(type(obj), cls)
.Добавлено в версии 3.2.
Также можно проверить создание исключений, предупреждений и сообщений журнала, используя следующие методы:
Метод Проверяет, что Новое в assertRaises(exc, fun, *args, **kwds)
fun(*args, **kwds)
вызывает excassertRaisesRegex(exc, r, fun, *args, **kwds)
fun(*args, **kwds)
вызывает exc и сообщение соответствия регулярному выражению r3.1 assertWarns(warn, fun, *args, **kwds)
fun(*args, **kwds)
вызывает warn3.2 assertWarnsRegex(warn, r, fun, *args, **kwds)
fun(*args, **kwds)
вызывает warn и сообщение соответствия регулярному выражению r3.2 assertLogs(logger, level)
with
блок логирует в logger с минимальным level3.4 -
assertRaises
(exception, callable, *args, **kwds)¶ -
assertRaises
(exception, *, msg=None) Проверяет, вызывается ли исключение при вызове callable с любыми позиционными или ключевыми аргументами, которые также передаются в
assertRaises()
. Если вызывается ошибка exception тест проходит. Если вызывается другое исключение или исключение не вызывается, то терпит неудачу. Чтобы перехватить любую группу исключений, кортеж, содержащий классы исключений, может быть передан как exception.Если указаны только аргументы exception и, возможно, msg, возвращает менеджер контекста, чтобы тестируемый код можно было записать встроенным, а не как функцию:
with self.assertRaises(SomeException): do_something()
При использовании в качестве менеджера контекста
assertRaises()
принимает дополнительный ключевой аргумент msg.Менеджер контекста сохранит перехваченный объект исключения в своем атрибуте
exception
. Это может быть полезно, если вы намерены выполнить дополнительные проверки возникшего исключения:with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3)
Изменено в версии 3.1: Добавлена возможность использовать
assertRaises()
в качестве менеджера контекста.Изменено в версии 3.2: Добавлен атрибут
exception
.Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
assertRaisesRegex
(exception, regex, callable, *args, **kwds)¶ -
assertRaisesRegex
(exception, regex, *, msg=None) Подобен
assertRaises()
, но также проверяет соответствие regex строковому представлению возникшего исключения. regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использованияre.search()
. Примеры:self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$", int, 'XYZ')
или:
with self.assertRaisesRegex(ValueError, 'literal'): int('XYZ')
Добавлено в версии 3.1: Добавлен под названием
assertRaisesRegexp
.Изменено в версии 3.2: Переименован в
assertRaisesRegex()
.Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
assertWarns
(warning, callable, *args, **kwds)¶ -
assertWarns
(warning, *, msg=None) Проверить, что предупреждение запускается при вызове callable с любыми позиционными аргументами или ключевыми аргументами, которые также передаются в
assertWarns()
. Тест проходит успешно, если срабатывает warning, и терпит неудачу, если это не так. Любое исключение — ошибка. Чтобы перехватить любую группу предупреждений, кортеж, содержащий классы предупреждений, может быть передан как warnings.Если указаны только аргументы warning и, возможно, msg, возвращает менеджер контекста, чтобы тестируемый код можно было записать встроенным, а не как функцию:
with self.assertWarns(SomeWarning): do_something()
При использовании в качестве менеджера контекста
assertWarns()
принимает дополнительный ключевой аргумент msg.Менеджер контекста сохранит перехваченный объект предупреждения в своём атрибуте
warning
, а исходную строку, которая инициировала предупреждения, в атрибутахfilename
иlineno
. Это может быть полезно, если вы намерены выполнить дополнительную проверку обнаруженного предупреждения:with self.assertWarns(SomeWarning) as cm: do_something() self.assertIn('myfile.py', cm.filename) self.assertEqual(320, cm.lineno)
Данный метод работает независимо от фильтров предупреждений, установленных при его вызове.
Добавлено в версии 3.2.
Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
assertWarnsRegex
(warning, regex, callable, *args, **kwds)¶ -
assertWarnsRegex
(warning, regex, *, msg=None) Подобно
assertWarns()
, но также проверяет соответствие regex сообщению о сработавшем предупреждении. regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использованияre.search()
. Пример:self.assertWarnsRegex(DeprecationWarning, r'legacy_function\(\) is deprecated', legacy_function, 'XYZ')
или:
with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'): frobnicate('/etc/passwd')
Добавлено в версии 3.2.
Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.
-
assertLogs
(logger=None, level=None)¶ Менеджер контекста для проверки того, что хотя бы одно сообщение зарегистрировано на logger или одном из его дочерних узлов, по крайней мере, с данным level.
Если задан logger, то он должен быть объектом
logging.Logger
илиstr
, отдающим имя логгера. По умолчанию используется корневой логгер, перехватывающий все сообщения, которые не были заблокированы нераспространяющимся потомком логгера.Если задан level, то он должен быть либо числовым уровнем журналирования, либо его строковым эквивалентом (например,
"ERROR"
илиlogging.ERROR
). По умолчанию —logging.INFO
.Тест считается успешным, если хотя бы одно сообщение, отправленное внутри блока
with
, соответствует условиям logger и level, в противном случае он не выполняется.Объект, возвращаемый менеджером контекста, является помощником записи, который отслеживает соответствующие сообщения журнала. У него есть два атрибута:
-
records
¶ Список объектов
logging.LogRecord
соответствующих сообщений журнала.
-
output
¶ Список объектов
str
с форматированным выводом совпадающих сообщений.
Пример:
with self.assertLogs('foo', level='INFO') as cm: logging.getLogger('foo').info('first message') logging.getLogger('foo.bar').error('second message') self.assertEqual(cm.output, ['INFO:foo:first message', 'ERROR:foo.bar:second message'])
Добавлено в версии 3.4.
-
Существуют также другие методы, используемые для выполнения более точных проверок, например:
Метод Проверяет, что Новое в assertAlmostEqual(a, b)
round(a-b, 7) == 0
assertNotAlmostEqual(a, b)
round(a-b, 7) != 0
assertGreater(a, b)
a > b
3.1 assertGreaterEqual(a, b)
a >= b
3.1 assertLess(a, b)
a < b
3.1 assertLessEqual(a, b)
a <= b
3.1 assertRegex(s, r)
r.search(s)
3.1 assertNotRegex(s, r)
not r.search(s)
3.2 assertCountEqual(a, b)
У a и b есть одинаковые элементы в одном и том же числе, независимо от их порядка. 3.2 -
assertAlmostEqual
(first, second, places=7, msg=None, delta=None)¶ -
assertNotAlmostEqual
(first, second, places=7, msg=None, delta=None)¶ Проверить, что first и second приблизительно (или не приблизительно) равны, вычислив разницу, округлив до заданного десятичного числа places (по умолчанию 7) и сравнив с нулем. Обратите внимание, что данные методы округляют значения до заданного числа десятичных знаков (т.е. как функция
round()
), а не значащих цифр.Если delta предоставляется вместо places, тогда разница между first и second должна быть меньше или равна (или больше) delta.
Подача delta и places вызывает
TypeError
.Изменено в версии 3.2:
assertAlmostEqual()
автоматически считает почти равные объекты, которые сравниваются, равными.assertNotAlmostEqual()
автоматически завершается ошибкой, если объекты сравниваются одинаково. Добавлен ключевой аргумент delta.
-
assertGreater
(first, second, msg=None)¶ -
assertGreaterEqual
(first, second, msg=None)¶ -
assertLess
(first, second, msg=None)¶ -
assertLessEqual
(first, second, msg=None)¶ Проверить, что first соответственно >, >=, < или <=, чем second, в зависимости от имени метода. В противном случае тест не состоится:
>>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4"
Добавлено в версии 3.1.
-
assertRegex
(text, regex, msg=None)¶ -
assertNotRegex
(text, regex, msg=None)¶ Убедиться, что поисковый запрос regex соответствует (или не соответствует) text. В случае сбоя сообщение об ошибке будет включать шаблон и text (или шаблон и часть text, которые неожиданно совпали). regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования
re.search()
.Добавлено в версии 3.1: Добавлен под названием
assertRegexpMatches
.Изменено в версии 3.2: Метод
assertRegexpMatches()
был переименован вassertRegex()
.Добавлено в версии 3.2:
assertNotRegex()
.Добавлено в версии 3.5: Имя
assertNotRegexpMatches
является устаревшим псевдонимом дляassertNotRegex()
.
-
assertCountEqual
(first, second, msg=None)¶ Убедиться, что последовательность first содержит те же элементы, что и second, независимо от их порядка. В противном случае будет сгенерировано сообщение об ошибке со списком различий между последовательностями.
Дублирующиеся элементы не игнорируются при сравнении first и second. Он проверяет, есть ли у каждого элемента одинаковое количество в обеих последовательностях. Эквивалентен:
assertEqual(Counter(list(first)), Counter(list(second)))
, но также работает с последовательностями не хэшируемых объектов.Добавлено в версии 3.2.
Метод
assertEqual()
отправляет проверку равенства для объектов одного типа различным методам, зависящим от типа. Данные методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощьюaddTypeEqualityFunc()
:-
addTypeEqualityFunc
(typeobj, function)¶ Регистрирует зависящий от типа метод, вызываемый
assertEqual()
, чтобы проверить, равны ли два объекта одного и того же typeobj (не подклассов). function должен принимать два позиционных аргумента и третий ключевой аргумент msg=None, как иassertEqual()
. Он должен вызватьself.failureException(msg)
при обнаружении неравенства между первыми двумя параметрами — возможно, с предоставлением полезной информации и подробным объяснением неравенства в сообщении об ошибке.Добавлено в версии 3.1.
Список методов, зависящих от типа, автоматически используемых
assertEqual()
, представлен в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать данные методы напрямую.Метод Используется для сравнения Новый в assertMultiLineEqual(a, b)
строки 3.1 assertSequenceEqual(a, b)
последовательности 3.1 assertListEqual(a, b)
списки 3.1 assertTupleEqual(a, b)
кортежи 3.1 assertSetEqual(a, b)
множества или замороженные множества 3.1 assertDictEqual(a, b)
словари 3.1 -
assertMultiLineEqual
(first, second, msg=None)¶ Убедиться, что многострочная строка first равна строке second. Если они не равны, разница двух строк, выделяющая различия, будет включена в сообщение об ошибке. Данный метод используется по умолчанию при сравнении строк с
assertEqual()
.Добавлено в версии 3.1.
-
assertSequenceEqual
(first, second, msg=None, seq_type=None)¶ Проверяет, что две последовательности равны. Если предоставлен seq_type, оба first и second должны быть экземплярами seq_type, иначе возникнет ошибка. Если последовательности отличаются, создаётся сообщение об ошибке, которое показывает разницу между ними.
Данный метод не вызывается напрямую
assertEqual()
, но он используется для реализацииassertListEqual()
иassertTupleEqual()
.Добавлено в версии 3.1.
-
assertListEqual
(first, second, msg=None)¶ -
assertTupleEqual
(first, second, msg=None)¶ Проверяет равенство двух списков или кортежей. В противном случае создаётся сообщение об ошибке, в котором показаны только различия между ними. Ошибка также вызывается, если у какого-либо из параметров неправильный тип. Данные методы используются по умолчанию при сравнении списков или кортежей с
assertEqual()
.Добавлено в версии 3.1.
-
assertSetEqual
(first, second, msg=None)¶ Проверяет, что два набора равны. В противном случае создаётся сообщение об ошибке, в котором перечислены различия между наборами. Данный метод используется по умолчанию при сравнении множеств или замороженных множеств с
assertEqual()
.Не работает, если в first или second нет метода
set.difference()
.Добавлено в версии 3.1.
-
assertDictEqual
(first, second, msg=None)¶ Проверить, что два словаря равны. В противном случае создаётся сообщение об ошибке, показывающее различия в словарях. Данный метод будет использоваться по умолчанию для сравнения словарей при обращении к
assertEqual()
.Добавлено в версии 3.1.
Наконец,
TestCase
предоставляет следующие методы и атрибуты:-
fail
(msg=None)¶ Безусловно сигнализирует об ошибке теста с msg или
None
в качестве сообщения об ошибке.
-
failureException
¶ Данный атрибут класса выдает исключение, вызванное тестовым методом. Если инфраструктура тестирования должна использовать специализированное исключение, возможно, для переноса дополнительной информации, она должна создать подкласс этого исключения, чтобы «играть честно» с платформой. Начальное значение этого атрибута —
AssertionError
.
-
longMessage
¶ Данный атрибут класса определяет, что происходит, когда пользовательское сообщение об ошибке передаётся в качестве аргумента msg вызову assertXYY, который завершается ошибкой.
True
— значение по умолчанию. В этом случае настраиваемое сообщение добавляется в конец стандартного сообщения об ошибке. Если задано значениеFalse
, настраиваемое сообщение заменяет стандартное сообщение.Настройку класса можно переопределить в отдельных методах тестирования, присвоив атрибут экземпляра self.longMessage
True
илиFalse
перед вызовом методов assert.Настройка класса сбрасывается перед каждым тестовым вызовом.
Добавлено в версии 3.1.
-
maxDiff
¶ Данный атрибут управляет максимальной длиной выводимых различий с помощью методов assert, которые сообщают о различиях в случае сбоя. По умолчанию это 80*8 символов. Данный атрибут затрагивает следующие методы утверждения:
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.
-
doCleanups
()¶ Данный метод вызывается безоговорочно после
tearDown()
или послеsetUp()
, еслиsetUp()
вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных
addCleanup()
. Если вам нужно, чтобы функции очистки вызывались с prior поtearDown()
, вы можете сами вызвать вdoCleanups()
.doCleanups()
извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любое время.Добавлено в версии 3.1.
-
classmethod
addClassCleanup
(function, /, *args, **kwargs)¶ Добавить функцию, которая будет вызываться после
tearDownClass()
для очистки ресурсов, используемых во время тестового класса. Функции будут вызываться в порядке, обратном порядку их добавления (LIFO). Они вызываются с любыми аргументами и ключевыми аргументами, переданными вaddClassCleanup()
при их добавлении.В случае сбоя
setUpClass()
, означающего, чтоtearDownClass()
не вызывается, все добавленные функции очистки будут вызываться.Добавлено в версии 3.8.
-
classmethod
doClassCleanups
()¶ Данный метод вызывается безоговорочно после
tearDownClass()
или послеsetUpClass()
, еслиsetUpClass()
вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных
addClassCleanup()
. Если вам нужно, чтобы функции очистки вызывались с prior по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)¶ Данный метод принимает корутину, которую можно использовать как функцию очистки.
-
run
(result=None)¶ Устанавливает новый событийный цикл для запуска теста, собирая результат в объект
TestResult
, переданный как result. Если result пропущен илиNone
, создаётся и используется временный объект результата (путём вызова методаdefaultTestResult()
). Объект результата возвращается вызывающей сторонеrun()
. В конце теста все задачи в цикле событий отменяются.
Пример, иллюстрирующий порядок:
from unittest import IsolatedAsyncioTestCase events = [] class Test(IsolatedAsyncioTestCase): def setUp(self): events.append("setUp") async def asyncSetUp(self): self._async_connection = await AsyncConnection() events.append("asyncSetUp") async def test_response(self): events.append("test_response") response = await self._async_connection.get("https://example.com") self.assertEqual(response.status_code, 200) self.addAsyncCleanup(self.on_cleanup) def tearDown(self): events.append("tearDown") async def asyncTearDown(self): await self._async_connection.close() events.append("asyncTearDown") async def on_cleanup(self): events.append("cleanup") if __name__ == "__main__": unittest.main()
После запуска теста
events
будет содержать["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]
.-
coroutine
-
class
unittest.
FunctionTestCase
(testFunc, setUp=None, tearDown=None, description=None)¶ Данный класс реализует часть интерфейса
TestCase
, позволяющий исполнителю тестов проводить тест, но не предоставляет методы, которые тестовый код может использовать для проверки и сообщения об ошибках. Он используется для создания тестовых случаев с использованием устаревшего тестового кода, что позволяет интегрировать его в тестовую среду на основеunittest
.
Устаревшие псевдонимы¶
По историческим причинам у некоторых из методов TestCase
был один или
несколько псевдонимов, которые теперь являются устаревшими. В следующей таблице
перечислены правильные имена вместе с их устаревшими псевдонимами:
Название метода Устаревший псевдоним Устаревший псевдоним assertEqual()
failUnlessEqual assertEquals assertNotEqual()
failIfEqual assertNotEquals assertTrue()
failUnless assert_ assertFalse()
failIf assertRaises()
failUnlessRaises assertAlmostEqual()
failUnlessAlmostEqual assertAlmostEquals assertNotAlmostEqual()
failIfAlmostEqual assertNotAlmostEquals assertRegex()
assertRegexpMatches assertNotRegex()
assertNotRegexpMatches assertRaisesRegex()
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
в данный множество тестов.Это эквивалентно повторению tests с вызовом
addTest()
для каждого элемента.
TestSuite
разделяет следующие методы сTestCase
:-
run
(result)¶ Запустить тесты, связанные с этим набором, собрав результат в объект результата теста, переданный как result. Обратите внимание, что в отличие от
TestCase.run()
,TestSuite.run()
требует передачи объекта результата.
-
debug
()¶ Запустить тесты, связанные с этим набором, без сбора результатов. Это позволяет распространять исключения, вызванные тестом, на вызывающую программу и может использоваться для поддержки выполнения тестов в отладчике.
-
countTestCases
()¶ Возвращает количество тестов, представленных этим тестовым объектом, включая все индивидуальные тесты и подмножества.
-
__iter__
()¶ Доступ к тестам, сгруппированным по
TestSuite
, всегда осуществляется итерацией. Подклассы могут лениво предоставлять тесты, переопределяя__iter__()
. Обратите внимание, что данный метод может вызываться несколько раз в одном множестве (например, при подсчете тестов или сравнении на равенство), поэтому тесты, возвращаемые повторными итерациями доTestSuite.run()
, должны быть одинаковыми для каждой итерации вызова. ПослеTestSuite.run()
вызывающие не должны полагаться на тесты, возвращаемые этим методом, если вызывающий не использует подкласс, который переопределяетTestSuite._removeTestAtIndex()
для сохранения ссылок на тесты.Изменено в версии 3.2: В более ранних версиях
TestSuite
обращался к тестам напрямую, а не через итерацию, поэтому переопределения__iter__()
было недостаточно для предоставления тестов.Изменено в версии 3.4: В более ранних версиях
TestSuite
содержал ссылки на каждыйTestCase
послеTestSuite.run()
. Подклассы могут восстановить это поведение, переопределивTestSuite._removeTestAtIndex()
.
При типичном использовании объекта
TestSuite
методrun()
вызываетсяTestRunner
, а не тестовой системой конечного пользователя.-
Загрузка и запуск тестов¶
-
class
unittest.
TestLoader
¶ Класс
TestLoader
используется для создания наборов тестов из классов и модулей. Обычно нет необходимости создавать экземпляр этого класса; модульunittest
предоставляет экземпляр, который можно использовать какunittest.defaultTestLoader
. Однако использование подкласса или экземпляра позволяет настраивать некоторые настраиваемые свойства.У объектов
TestLoader
есть следующие атрибуты:-
errors
¶ Список не критических ошибок, обнаруженных при загрузке тестов. Ни в какой момент не сбрасывается загрузчиком. О критических ошибках сигнализирует соответствующий метод, вызывающий исключение для вызывающей стороны. На не критические ошибки также указывает синтетический тест, который при запуске вызывает исходную ошибку.
Добавлено в версии 3.5.
У объектов
TestLoader
следующие методы:-
loadTestsFromTestCase
(testCaseClass)¶ Возвращает множество всех тестовых случаев, содержащихся в производном от
TestCase
testCaseClass
.Экземпляр тестового набора создаётся для каждого метода с именем
getTestCaseNames()
. По умолчанию это имена методов, начинающиеся сtest
. ЕслиgetTestCaseNames()
не возвращает никаких методов, но реализован методrunTest()
, вместо этого создаётся один тестовый пример для этого метода.
-
loadTestsFromModule
(module, pattern=None)¶ Возвращает множество всех тестовых примеров, содержащихся в данном модуле. Данный метод ищет в module классы, производные от
TestCase
, и создаёт экземпляр класса для каждого метода тестирования, определённого для этого класса.Примечание
Хотя использование иерархии классов, производных от
TestCase
, может быть удобно при совместном использовании фикстур и вспомогательных функций, определение методов тестирования на базовых классах, которые не предназначены для непосредственного создания экземпляров, не очень хорошо сочетается с этим методом. Однако это может быть полезно, когда фикстуры различны и определены в подклассах.Если модуль предоставляет функцию
load_tests
, он будет вызван для загрузки тестов. Это позволяет модулям настраивать тестовую загрузку. Это протокол load_tests. Аргумент 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, содержащий их. Будут загружены только тестовые файлы, соответствующие pattern. (Использование сопоставления с шаблоном стиля оболочки.) Будут загружены только имена модулей, которые можно импортировать (т. е. допустимые идентификаторы Python).
Все тестовые модули должны быть импортированы с верхнего уровня проекта. Если начальный каталог не является каталогом верхнего уровня, тогда каталог верхнего уровня должен быть указан отдельно.
Если при импорте модуля произошел сбой, например, из-за синтаксической ошибки, это будет записано как отдельная ошибка, и обнаружение будет продолжено. Если сбой импорта вызван возбуждением
SkipTest
, это будет записано как пропуск вместо ошибки.Если пакет (каталог, содержащий файл с именем
__init__.py
) найден, пакет будет проверен на наличие функцииload_tests
. Если он существует, он будет называтьсяpackage.load_tests(loader, tests, pattern)
. Обнаружение тестов заботится о том, чтобы пакет проверялся на наличие тестов только один раз во время вызова, даже если сама функция load_tests вызываетloader.discover
.Если
load_tests
существует, то обнаружение не рекурсивно входит в пакет,load_tests
отвечает за загрузку всех тестов в пакете.Шаблон намеренно не сохраняется в качестве атрибута загрузчика, чтобы пакеты могли продолжить обнаружение самостоятельно. top_level_dir сохраняется, поэтому
load_tests
не нужно передавать данный аргумент вloader.discover()
.start_dir может быть разделенным точками именем модуля, а также каталогом.
Добавлено в версии 3.2.
Изменено в версии 3.4: Модули, которые вызывают
SkipTest
при импорте, записываются как пропуски не ошибки. Открытие работает на пакетах пространства имён. Перед импортом пути сортируются в порядке выполнения то же самое, даже если порядок в базовой файловой системе не такой зависит от имени файла.Изменено в версии 3.5: Найденные пакеты теперь проверяются на
load_tests
независимо от того, соответствует ли их путь pattern, поскольку имя пакета не может соответствовать шаблону по умолчанию.
Следующие атрибуты
TestLoader
можно настроить либо путём создания подкласса, либо путём присвоения экземпляру:-
testMethodPrefix
¶ Строка с префиксом имён методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию —
'test'
.Это влияет на
getTestCaseNames()
и все методыloadTestsFrom*()
.
-
sortTestMethodsUsing
¶ Функция, которая будет использоваться для сравнения имён методов при их сортировке в
getTestCaseNames()
и во всех методахloadTestsFrom*()
.
-
suiteClass
¶ Вызываемый объект, который создаёт множество тестов из списка тестов. Никаких методов для полученного объекта не требуется. Значение по умолчанию — класс
TestSuite
.Влияет на все методы
loadTestsFrom*()
.
-
testNamePatterns
¶ Список шаблонов имён тестов с подстановочными знаками в стиле оболочки Unix, которым должны соответствовать методы тестирования, чтобы их можно было включить в наборы тестов (см. параметр
-v
).Если данный атрибут не
None
(по умолчанию), все методы тестирования, которые должны быть включены в наборы тестов, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что совпадения всегда выполняются с использованиемfnmatch.fnmatchcase()
, поэтому в отличие от шаблонов, переданных в параметр-v
, простые шаблоны подстроки должны быть преобразованы с использованием подстановочных знаков*
.Влияет на все методы
loadTestsFrom*()
.Добавлено в версии 3.7.
-
-
class
unittest.
TestResult
¶ Данный класс используется для сбора информации о том, какие тесты прошли успешно, а какие нет.
Объект
TestResult
хранит результаты набора тестов. КлассыTestCase
иTestSuite
обеспечивают правильную запись результатов; авторам тестов не нужно беспокоиться о записи результатов тестов.Фреймворкам тестирования, построенным на основе
unittest
, может потребоваться доступ к объектуTestResult
, сгенерированному путём выполнения набора тестов для целей отчетности; для этой цели методTestRunner.run()
возвращает экземплярTestResult
.У экземпляров
TestResult
есть следующие атрибуты, которые будут интересны при проверке результатов выполнения набора тестов:-
errors
¶ Список, содержащий 2 кортежа экземпляров
TestCase
и строк, содержащих отформатированные трассировки. Каждый кортеж представляет собой тест, вызвавший неожиданное исключение.
-
failures
¶ Список, содержащий 2 кортежа экземпляров
TestCase
и строк, содержащих отформатированные трассировки. Каждый кортеж представляет собой тест, в котором с помощью методовTestCase.assert*()
явным образом сообщается об ошибке.
-
skipped
¶ Список, содержащий 2 кортежа экземпляров
TestCase
и строк, содержащих причину пропуска теста.Добавлено в версии 3.1.
-
expectedFailures
¶ Список, содержащий 2 кортежа экземпляров
TestCase
и строк, содержащих отформатированные трассировки. Каждый кортеж представляет собой ожидаемый сбой или ошибку тестового случая.
-
unexpectedSuccesses
¶ Список, содержащий экземпляры
TestCase
, которые были помечены как ожидаемые сбои, но завершились успешно.
-
testsRun
¶ Общее количество выполненных тестов.
-
buffer
¶ Если установлено значение истина,
sys.stdout
иsys.stderr
будут буферизироваться между вызовамиstartTest()
иstopTest()
. Собранные выходные данные будут отражены на реальныхsys.stdout
иsys.stderr
только в случае сбоя теста или ошибок. Любой вывод также прилагается к сообщению об ошибке/сбое.Добавлено в версии 3.2.
-
failfast
¶ Если установлено значение истина,
stop()
будет вызываться при первом сбое или ошибке, останавливая тестовый прогон.Добавлено в версии 3.2.
-
tb_locals
¶ Если установлено значение истина, то в трассировке будут отображаться локальные переменные.
Добавлено в версии 3.5.
-
wasSuccessful
()¶ Возвращает
True
, если все запущенные тесты прошли успешно, в противном случае возвращаетFalse
.Изменено в версии 3.4: Возвращает
False
, если из тестов, отмеченных декораторомexpectedFailure()
, было какое-либоunexpectedSuccesses
.
-
stop
()¶ Данный метод можно вызвать, чтобы сигнализировать о том, что множество выполняемых тестов следует прервать, установив для атрибута
shouldStop
значениеTrue
. ОбъектыTestRunner
должны учитывать данный флаг и возвращаться без выполнения каких-либо дополнительных тестов.Например, данная функция используется классом
TextTestRunner
для остановки тестового фреймворка, когда пользователь сигнализирует о прерывании с клавиатуры. Интерактивные инструменты, которые предоставляют реализацииTestRunner
, могут использовать это аналогичным образом.
Следующие методы класса
TestResult
используются для поддержки внутренних структур данных и могут быть расширены в подклассах для поддержки дополнительных требований к отчетности. Это особенно полезно при создании инструментов, поддерживающих интерактивную отчетность во время выполнения тестов.-
startTest
(test)¶ Вызывается, когда будет запущен тестовый пример test.
-
stopTest
(test)¶ Вызывается после выполнения тестового примера test, независимо от результата.
-
startTestRun
()¶ Вызывается один раз перед выполнением любых тестов.
Добавлено в версии 3.1.
-
stopTestRun
()¶ Вызывается один раз после выполнения всех тестов.
Добавлено в версии 3.1.
-
addError
(test, err)¶ Вызывается, когда тестовый пример test вызывает непредвиденное исключение. err — это кортеж в форме, возвращаемой
sys.exc_info()
:(type, value, traceback)
.Реализация по умолчанию добавляет кортеж
(test, formatted_err)
к атрибутуerrors
экземпляра, где formatted_err — это отформатированная трассировка, полученная из err.
-
addFailure
(test, err)¶ Вызывается, когда тестовый пример test сигнализирует об ошибке. err — это кортеж в форме, возвращаемой
sys.exc_info()
:(type, value, traceback)
.Реализация по умолчанию добавляет кортеж
(test, formatted_err)
к атрибутуfailures
экземпляра, где formatted_err — это отформатированная трассировка, полученная из err.
-
addSuccess
(test)¶ Вызывается, когда тестовый пример test завершается успешно.
Реализация по умолчанию ничего не делает.
-
addSkip
(test, reason)¶ Вызывается, когда тестовый пример test пропускается. reason — причина пропуска теста.
Реализация по умолчанию добавляет кортеж
(test, reason)
к атрибутуskipped
экземпляра.
-
addExpectedFailure
(test, err)¶ Вызывается, когда тестовый пример test вызывает сбой или ошибки, но был помечен декоратором
expectedFailure()
.Реализация по умолчанию добавляет кортеж
(test, formatted_err)
к атрибутуexpectedFailures
экземпляра, где formatted_err — это отформатированная трассировка, полученная из err.
-
addUnexpectedSuccess
(test)¶ Вызывается, когда тестовый пример test был помечен декоратором
expectedFailure()
, но успешно.Реализация по умолчанию добавляет тест к атрибуту экземпляра
unexpectedSuccesses
.
-
addSubTest
(test, subtest, outcome)¶ Вызывается по завершении подтеста. test — это тестовый пример, соответствующий методу тестирования. subtest — это пользовательский экземпляр
TestCase
, реализующий подтест.Если outcome —
None
, подтест прошёл успешно. В противном случае произошёл сбой, за исключением случая, когда outcome — это кортеж в форме, возвращаемойsys.exc_info()
:(type, value, traceback)
.Реализация по умолчанию ничего не делает, когда результат является успешным, и записывает сбои подтестов как обычные сбои.
Добавлено в версии 3.4.
-
-
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
, даже если они игнорируется по умолчанию. Предупреждения об устаревании, вызванные устаревшими методами unittest, также имеют специальный регистр, и, если фильтры предупреждений'default'
или'always'
, они будут появляться только один раз для каждого модуля, чтобы избежать слишком большого количества предупреждающих сообщений. Это поведение можно изменить с помощью параметров Python-Wd
или-Wa
(см. Управление предупреждениями) и оставив warnings на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 может быть либо классом исполнителя тестов, либо уже созданным его экземпляром. По умолчанию
main
вызываетsys.exit()
с кодом выхода, указывающим на успешное или неудачное выполнение тестов.Аргумент testLoader должен быть экземпляром
TestLoader
и принимать значение по умолчаниюdefaultTestLoader
.main
поддерживает использование из интерактивного интерпретатора путём передачи аргументаexit=False
. Результат отобразится на стандартном выходе без вызоваsys.exit()
:>>> from unittest import main >>> main(module='test_module', exit=False)
У параметров failfast, catchbreak и buffer тот же эффект, что и одноименные параметры командной строки.
Аргумент warnings указывает фильтр предупреждений, который следует использовать при выполнении тестов. Если он не указан, он останется
None
, если параметр-W
передан в python (см. Управление предупреждениями), в противном случае он будет установлен на'default'
.Вызов
main
фактически возвращает экземпляр класса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)
где 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):
# каталог верхнего уровня, кэшированный в экземпляре загрузчика
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 больше не проверяет имена пакетов на соответствие pattern из-за невозможности совпадения имён пакетов с шаблоном по умолчанию.
Фикстуры классов и модулей¶
Фикстуры на уровне классов и модулей реализованы в TestSuite
. Когда
множество тестов встречает тест из нового класса, вызывается
tearDownClass()
из предыдущего класса (если он есть), а затем
setUpClass()
из нового класса.
Точно так же, если тест из другого модуля из предыдущего теста, то запускается
tearDownModule
из предыдущего модуля, а затем setUpModule
из нового
модуля.
После выполнения всех тестов запускаются финальные tearDownClass
и
tearDownModule
.
Обратите внимание, что общие фикстуры плохо сочетаются с [потенциальными] функциями, такими как распараллеливание тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.
По умолчанию тесты, создаваемые загрузчиками модульных тестов, объединяют все
тесты из одних и тех же модулей и классов. Это приведет к тому, что
setUpClass
/setUpModule
(и т. д.) Будет вызываться ровно один раз для
каждого класса и модуля. Если вы рандомизируете порядок, чтобы тесты из разных
модулей и классов были смежными друг с другом, то данные общие функции фикстуры
могут вызываться несколько раз за один прогон теста.
Общие фикстуры не предназначены для работы с наборами с нестандартным
порядком. BaseTestSuite
все ещё существует для фреймворков, которые не хотят
поддерживать общие фикстуры.
Если вызываются какие-либо исключения во время одной из общих функций фикстур,
тест регистрируется как ошибка. Поскольку нет соответствующего тестового
экземпляра, создаётся объект _ErrorHolder
(у которого тот же интерфейс,
что и TestCase
) для представления ошибки. Если вы просто используете
стандартную программу запуска модульных тестов, данная деталь не играет роли,
но если вы являетесь автором фреймворка, она может быть актуальной.
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()
вызывает исключение.Она отвечает за вызов всех функций очистки, добавленных
addCleanupModule()
. Если вам нужно, чтобы функции очистки вызывались с prior поtearDownModule()
, вы можете сами вызвать вdoModuleCleanups()
.doModuleCleanups()
извлекает методы из стека функций очистки по одному, поэтому его можно вызывать в любое время.Добавлено в версии 3.8.
Обработка сигналов¶
Добавлено в версии 3.2.
Параметр командной строки -c/--catch
для unittest,
наряду с параметром catchbreak
для unittest.main()
, обеспечивает
более удобную обработку control-C во время выполнения теста. Если включено
поведение перехвата прерывания, control-C позволит завершить текущий тест, а
затем тестовый прогон завершится и сообщит обо всех полученных на данный момент
результатах. Второй control-c вызовет KeyboardInterrupt
обычным
способом.
Обработчик сигнала обработки control-c пытается оставаться совместимым с кодом
или тестами, которые устанавливают собственный обработчик
signal.SIGINT
. Если обработчик unittest
вызван, а не
установленный обработчик signal.SIGINT
, т. е. он был заменён
тестируемой системой и делегирован ей, то он вызывает обработчик по умолчанию.
Обычно это ожидаемое поведение кода, который заменяет установленный обработчик
и делегирует ему полномочия. Для отдельных тестов, требующих отключения
unittest
control-c, можно использовать декоратор removeHandler()
.
У авторов фреймворков есть несколько служебных функций, позволяющих реализовать в тестовых фреймворках функциональность обработки control-c.
-
unittest.
installHandler
()¶ Устанавливает обработчик control-c. При получении
signal.SIGINT
(обычно в ответ на нажатие пользователем Ctrl-c) для всех зарегистрированных результатов вызываетсяstop()
.
-
unittest.
registerResult
(result)¶ Зарегистрировать объект
TestResult
для обработки control-c. При регистрации результата сохраняется слабая ссылка на него, поэтому это не препятствует сборке мусора.Регистрация объекта
TestResult
не приводит к побочным эффектам, если обработка control-c не включена, поэтому среды тестирования могут безоговорочно регистрировать все результаты, которые они создают, независимо от того, включена ли обработка.
-
unittest.
removeResult
(result)¶ Удалить зарегистрированный результат. После удаления результата
stop()
больше не будет вызываться для этого объекта результата в ответ на control-c.
-
unittest.
removeHandler
(function=None)¶ При вызове без аргументов данная функция удаляет обработчик control-c, если он был установлен. Эту функцию также можно использовать в качестве декоратора теста для временного удаления обработчика во время выполнения теста:
@unittest.removeHandler def test_signal_handling(self): ...