unittest — Фреймворк для модульного тестирования
Исходный код: Lib/unittest/__init__.py
(Если вы уже знакомы с основными понятиями тестирования, можете перейти к списку методов assert.)
Фреймворк unittest для модульного тестирования был первоначально вдохновлён JUnit и имеет сходное назначение с основными фреймворками для модульного тестирования на других языках. Он поддерживает автоматизацию тестирования, совместное использование кода подготовки и завершения для тестов, агрегацию тестов в коллекции и независимость тестов от фреймворка отчётов.
Для достижения этого unittest поддерживает некоторые важные концепции объектно-ориентированным способом:
- тестовый фикстур
-
Тестовый фикстур представляет собой подготовку, необходимую для выполнения одного или нескольких тестов, а также любые связанные действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск процесса сервера.
- тестовый случай
-
Тестовый случай — это индивидуальная единица тестирования. Он проверяет конкретный ответ на определённый набор входных данных.
unittestпредоставляет базовый классTestCase, который можно использовать для создания новых тестовых случаев. - тестовый набор
-
Тестовый набор — это набор тестовых случаев, тестовых наборов или их сочетание. Он используется для агрегации тестов, которые должны выполняться вместе.
- тестовый запуск
-
Тестовый запуск — это компонент, который организует выполнение тестов и предоставляет результаты пользователю. Запуск может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение, чтобы указать результаты выполнения тестов.
См. также
-
Moduledoctest -
Другой модуль поддержки тестирования с совершенно другим подходом.
- Simple Smalltalk Testing: With Patterns
-
Оригинальная статья Кента Бека о фреймворках для тестирования, использующих шаблон, используемый
unittest. - pytest
-
Фреймворк для модульного тестирования сторонних разработчиков с более лёгким синтаксисом для написания тестов. Например,
assert func(10) == 42. - Классификация инструментов тестирования Python
-
Обширный список инструментов тестирования Python, включая фреймворки для функционального тестирования и библиотеки для имитации объектов.
- Список рассылки по тестированию в Python
-
Группа по интересам для обсуждения тестирования и инструментов тестирования в Python.
Скрипт Tools/unittestgui/unittestgui.py в дистрибутиве исходного кода Python представляет собой инструмент графического интерфейса для обнаружения и запуска тестов. Это в основном предназначено для удобства использования для тех, кто только начинает работать с модульным тестированием. Для производственных сред рекомендуется использовать систему непрерывной интеграции, например, Buildbot, Jenkins или Hudson.
Базовый пример
Модуль unittest предоставляет богатый набор инструментов для построения и запуска тестов. В этом разделе показано, что небольшого подмножества инструментов достаточно для большинства пользователей.
Вот короткий скрипт для тестирования трёх методов строк:
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
unittest.main()
Тестовый случай создаётся путём наследования класса unittest.TestCase. Три отдельных теста определяются методами, имена которых начинаются с букв test. Этот соглашение об именовании информирует тестовый запуск о том, какие методы представляют собой тесты.
Суть каждого теста — вызов assertEqual() для проверки ожидаемого результата; assertTrue() или assertFalse() для проверки условия; или assertRaises() для проверки того, что возникает конкретное исключение. Эти методы используются вместо оператора assert, чтобы тестовый запуск мог накапливать все результаты тестов и генерировать отчёт.
Методы setUp() и tearDown() позволяют определить инструкции, которые будут выполняться до и после каждого тестового метода. Они рассматриваются более подробно в разделе Организация кода тестов.
Последний блок демонстрирует простой способ запуска тестов. unittest.main() обеспечивает интерфейс командной строки для тестового скрипта. При запуске из командной строки вышеуказанный скрипт даёт результат, похожий на этот:
... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Передача параметра -v вашему тестовому скрипту укажет unittest.main() на включение более подробного режима, и получите следующий вывод:
test_isupper (__main__.TestStringMethods) ... ok test_split (__main__.TestStringMethods) ... ok test_upper (__main__.TestStringMethods) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
В приведённых выше примерах показаны наиболее часто используемые функции unittest, которые достаточно для многих повседневных потребностей тестирования. Остальная часть документации исследует весь набор функций с основ.
Интерфейс командной строки
Модуль unittest можно использовать из командной строки для запуска тестов из модулей, классов или даже отдельных тестовых методов:
python -m unittest test_module1 test_module2 python -m unittest test_module.TestClass python -m unittest test_module.TestClass.test_method
Вы можете передать список с любым сочетанием имён модулей и полных квалифицированных имён классов или методов.
Тестовые модули можно указать путём файла:
python -m unittest tests/test_something.py
Это позволяет вам использовать автодополнение имён файлов в оболочке для указания тестового модуля. Указанный файл должен по-прежнему быть импортируемым как модуль. Путь преобразуется в имя модуля путём удаления '.py' и преобразования разделителей путей в '. '. Если вы хотите выполнить тестовый файл, который не является импортируемым как модуль, вы должны запустить файл напрямую.
Вы можете запустить тесты с большей детализацией (более высокий уровень подробности), передав флаг -v:
python -m unittest -v test_module
При выполнении без аргументов запускается Обнаружение тестов:
python -m unittest
Для получения списка всех параметров командной строки:
python -m unittest -h
Изменено в версии 3.2: В более ранних версиях было возможно запустить только отдельные тестовые методы, а не модули или классы.
Параметры командной строки
unittest поддерживает следующие параметры командной строки:
-
-b, --buffer -
Потоки стандартного вывода и стандартной ошибки буферизируются во время выполнения теста. Вывод во время прохождения теста отбрасывается. Вывод отображается обычно при ошибке или сбое теста и добавляется к сообщениям об ошибках.
-
-c, --catch -
Ctrl+C во время выполнения теста ожидает завершения текущего теста, а затем сообщает о всех результатах до этого момента. Второй Ctrl+C вызывает обычное исключение
KeyboardInterrupt.См. Обработка сигналов для функций, которые предоставляют эту функциональность.
-
-f, --failfast -
Останавливает выполнение теста при первой ошибке или сбое.
-
-k -
Запускает только тестовые методы и классы, которые соответствуют шаблону или подстроке. Этот параметр можно использовать несколько раз, в этом случае включаются все тестовые случаи, соответствующие заданным шаблонам.
Шаблоны, содержащие символ подстановки (
*), сопоставляются с именем теста с помощьюfnmatch.fnmatchcase(); в противном случае используется простое сопоставление подстрок, чувствительное к регистру.Шаблоны сопоставляются с полным квалифицированным именем тестового метода, как импортированным загрузчиком тестов.
Например,
-k fooсоответствуетfoo_tests.SomeTest.test_something,bar_tests.SomeTest.test_foo, но неbar_tests.FooTest.test_something.
-
--locals -
Показывает локальные переменные в трассировках.
Добавлено в версии 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 предоставляет механизм для этого: тестовый набор, представленный классом unittest’s TestSuite. В большинстве случаев вызов unittest.main() сделает все правильно и соберет все тестовые случаи модуля для выполнения.
Однако, если вы хотите настроить построение тестового набора самостоятельно:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_widget_size'))
suite.addTest(WidgetTestCase('test_widget_resize'))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
Вы можете поместить определения тестовых случаев и тестовых наборов в те же модули, что и код, который они тестируют (например, widget.py), но есть несколько преимуществ размещения тестового кода в отдельном модуле, например, test_widget.py.
- Тестовый модуль может выполняться автономно из командной строки.
- Тестовый код может быть легче отделен от распространяемого кода.
- Существует меньше соблазна изменять тестовый код, чтобы он соответствовал тестируемому коду, без веской причины.
- Тестовый код должен изменяться гораздо реже, чем код, который он тестирует.
- Тестируемый код может быть легче переработан.
- Тесты для модулей, написанных на C, должны быть в отдельных модулях, так что почему бы не придерживаться согласованности?
- Если стратегия тестирования изменится, нет необходимости изменять исходный код.
Использование старого кода тестов
Некоторые пользователи могут обнаружить, что у них есть существующий код тестов, который они хотели бы запустить из unittest, не преобразовывая каждый старый тестовый функцию в подкласс TestCase.
По этой причине unittest предоставляет класс FunctionTestCase. Этот подкласс TestCase может быть использован для обертывания существующей тестовой функции. Также можно предоставить функции настройки и завершения.
Учитывая следующую тестовую функцию:
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
можно создать эквивалентный экземпляр тестового случая следующим образом, с необязательными методами настройки и завершения:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
Примечание
Несмотря на то, что FunctionTestCase можно использовать для быстрого переноса существующего набора тестов в систему на основе unittest, такой подход не рекомендуется. Выделение времени для настройки надлежащих подклассов TestCase значительно облегчит будущие рефакторинги тестов.
В некоторых случаях существующие тесты могут быть написаны с использованием модуля doctest. В таком случае doctest предоставляет класс, который может автоматически создавать экземпляры unittest.TestSuite из существующих тестов на основе doctest.
Пропуск тестов и ожидаемые ошибки
Введено в версии 3.1.
Unittest поддерживает пропуск отдельных тестовых методов и целых классов тестов. Кроме того, он поддерживает пометку теста как «ожидаемой ошибки» — теста, который сломан и потерпит неудачу, но не должен учитываться как неудача в TestResult.
Пропуск теста — это просто использование декоратора skip() или одного из его условных вариантов, вызов TestCase.skipTest() внутри метода setUp() или теста, или прямое поднятие исключения SkipTest.
Базовый пропуск выглядит так:
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
def test_maybe_skipped(self):
if not external_resource_available():
self.skipTest("external resource not available")
# test code that depends on the external resource
pass
Это вывод выполнения примера выше в подробном режиме:
test_format (__main__.MyTestCase) ... 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):
"""
Test that numbers between 0 and 5 are all even.
"""
for i in range(0, 6):
with self.subTest(i=i):
self.assertEqual(i % 2, 0)
выведет следующий вывод:
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=3)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even (__main__.NumbersTest) (i=5)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
Без использования подтеста выполнение остановится после первой неудачи, и ошибка будет сложнее для диагностики, так как значение i не будет отображено:
======================================================================
FAIL: test_even (__main__.NumbersTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "subtests.py", line 32, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
Классы и функции
В этом разделе подробно описан API unittest.
Тестовые случаи
-
class unittest.TestCase(methodName='runTest') -
Экземпляры класса
TestCaseпредставляют логические тестовые единицы в вселеннойunittest. Этот класс предназначен для использования в качестве базового класса, при этом конкретные тесты реализуются в производных классах. Этот класс реализует интерфейс, необходимый для тестового исполнителя, чтобы он мог управлять тестами, и методы, которые может использовать тестовый код для проверки и сообщения об различных типах сбоев.Каждый экземпляр
TestCaseбудет запускать единственный базовый метод: метод с именем methodName. В большинстве случаев использованияTestCase, вы не будете изменять methodName и не переопределять метод по умолчаниюrunTest().Изменено в версии 3.2:
TestCaseможно успешно создать, не указывая methodName. Это упрощает эксперименты сTestCaseиз интерактивного интерпретатора.Экземпляры
TestCaseпредоставляют три группы методов: одна группа используется для запуска теста, другая используется реализацией теста для проверки условий и сообщения о сбоях, и некоторые методы запроса, позволяющие собирать информацию о самом тесте.Методы в первой группе (запуск теста) следующие:
-
setUp() -
Метод, вызываемый для подготовки тестовой среды. Он вызывается непосредственно перед вызовом тестового метода; за исключением
AssertionErrorилиSkipTest, любое исключение, возбужденное этим методом, будет рассматриваться как ошибка, а не как сбой теста. По умолчанию реализация ничего не делает.
-
tearDown() -
Метод, вызываемый непосредственно после вызова тестового метода и записи результата. Он вызывается даже если тестовый метод возбудил исключение, поэтому реализация в производных классах может потребовать особого внимания к проверке внутреннего состояния. Любое исключение, кроме
AssertionErrorилиSkipTest, возбужденное этим методом, будет рассматриваться как дополнительная ошибка, а не как сбой теста (тем самым увеличивая общее количество сообщенных ошибок). Этот метод будет вызван только в случае успешного выполнения методаsetUp(), независимо от результата выполнения тестового метода. По умолчанию реализация ничего не делает.
-
setUpClass() -
Метод класса, вызываемый перед запуском тестов в отдельном классе.
setUpClassвызывается с классом в качестве единственного аргумента и должен быть помечен какclassmethod():@classmethod def setUpClass(cls): ...См. Фикстуры класса и модуля для получения дополнительной информации.
Введено в версии 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 для проверки и сообщения о сбоях. В следующей таблице перечислены наиболее часто используемые методы (более подробную информацию см. в таблицах ниже):Метод
Проверяет, что
Введено в
a == ba != bbool(x) is Truebool(x) is Falsea is b3.1
a is not b3.1
x is None3.1
x is not None3.1
a in b3.1
a not in b3.1
isinstance(a, b)3.2
not isinstance(a, b)3.2
Все методы assert принимают аргумент msg, который, если указан, используется в качестве сообщения об ошибке при сбое (также см.
longMessage). Обратите внимание, что аргумент ключевого слова msg может быть передан вassertRaises(),assertRaisesRegex(),assertWarns(),assertWarnsRegex()только при использовании в качестве менеджера контекста. -
-
assertEqual(first, second, msg=None) -
Проверка, что first и second равны. Если значения не равны, тест завершится с ошибкой.
Кроме того, если first и second имеют один и тот же тип и являются списком, кортежем, словарем, множеством, неизменяемым множеством или строкой, или любым типом, который подкласс регистрирует с помощью
addTypeEqualityFunc(), то будет вызвана функция равенства для данного типа, чтобы сгенерировать более полезное сообщение об ошибке (см. также список методов для конкретных типов).Изменено в версии 3.1: Добавлена автоматическая вызов функции равенства для конкретных типов.
Изменено в версии 3.2:
assertMultiLineEqual()добавлена в качестве функции проверки равенства по умолчанию для сравнения строк.
-
assertNotEqual(first, second, msg=None) -
Проверка, что first и second не равны. Если значения равны, тест завершится с ошибкой.
-
assertTrue(expr, msg=None) -
assertFalse(expr, msg=None) -
Проверка, что expr истинно (или ложно).
Обратите внимание, что это эквивалентно
bool(expr) is Trueи не эквивалентноexpr is True(используйтеassertIs(expr, True)для последнего). Этот метод также следует избегать, когда доступны более специфичные методы (например,assertEqual(a, b)вместоassertTrue(a == b)), поскольку они предоставляют более подробное сообщение об ошибке в случае неудачи.
-
assertIs(first, second, msg=None) -
assertIsNot(first, second, msg=None) -
Проверка, что first и second оцениваются (или не оцениваются) как один и тот же объект.
Добавлена в версии 3.1.
-
assertIsNone(expr, msg=None) -
assertIsNotNone(expr, msg=None) -
Проверка, что expr является (или не является)
None.Добавлена в версии 3.1.
-
assertIn(member, container, msg=None) -
assertNotIn(member, container, msg=None) -
Проверка, что member находится (или не находится) в container.
Добавлена в версии 3.1.
-
assertIsInstance(obj, cls, msg=None) -
assertNotIsInstance(obj, cls, msg=None) -
Проверка, что obj является (или не является) экземпляром cls (который может быть классом или кортежем классов, как поддерживается
isinstance()). Чтобы проверить точный тип, используйтеassertIs(type(obj), cls).Добавлена в версии 3.2.
Также можно проверить возникновение исключений, предупреждений и сообщений протокола с помощью следующих методов:
Метод
Проверяет, что
Добавлена в
fun(*args, **kwds)вызывает excfun(*args, **kwds)вызывает exc, и сообщение соответствует регулярному выражению r3.1
fun(*args, **kwds)вызывает warn3.2
fun(*args, **kwds)вызывает warn, и сообщение соответствует регулярному выражению r3.2
В блоке
withпротокол в logger с минимальным уровнем level3.4
-
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) -
Менеджер контекста для проверки того, что по крайней мере одно сообщение записано в журнал или в одном из его дочерних элементов, с указанным уровнем.
Если указан, журнал должен быть объектом
logging.Loggerили строкой, содержащей имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения.Если указан, уровень должен быть либо числовым уровнем ведения журнала, либо его строковым эквивалентом (например, либо
"ERROR"илиlogging.ERROR). По умолчаниюlogging.INFO.Тест проходит, если по крайней мере одно сообщение, выпущенное внутри блока
with, соответствует условиям журнал и уровень; в противном случае тест завершается неудачно.Объект, возвращаемый менеджером контекста, является вспомогательным объектом для записи, который отслеживает соответствующие логические сообщения. Он имеет два атрибута:
-
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.
-
Также существуют другие методы, используемые для выполнения более специфических проверок, такие как:
Метод
Проверяет, что
Новая в
round(a-b, 7) == 0round(a-b, 7) != 0a > b3.1
a >= b3.1
a < b3.1
a <= b3.1
r.search(s)3.1
not r.search(s)3.2
Элементы a и b имеют одинаковое количество элементов в том же порядке, независимо от их порядка.
3.2
-
assertAlmostEqual(first, second, places=7, msg=None, delta=None) -
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None) -
Проверка, что первый и второй приблизительно (или не приблизительно) равны, вычисляя разницу, округляя до заданного количества десятичных знаков (по умолчанию 7) и сравнивая с нулём. Обратите внимание, что эти методы округляют значения до заданного количества десятичных знаков (как функция
round()), а не значащих цифр.Если вместо places задано delta, то разница между первым и вторым значениями должна быть меньше или равна (или больше) delta.
Если заданы и delta, и places, возникает исключение
TypeError.Изменено в версии 3.2:
assertAlmostEqual()автоматически рассматривает почти равные объекты, которые сравниваются как равные.assertNotAlmostEqual()автоматически завершает выполнение, если объекты сравниваются как равные. Добавлено ключевое слово delta.
-
assertGreater(first, second, msg=None) -
assertGreaterEqual(first, second, msg=None) -
assertLess(first, second, msg=None) -
assertLessEqual(first, second, msg=None) -
Проверка, что первое соответственно >, >=, < или <= чем второе в зависимости от имени метода. В противном случае тест завершится неудачно:
>>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4"
Новая в версии 3.1.
-
assertRegex(text, regex, msg=None) -
assertNotRegex(text, regex, msg=None) -
Проверка, что поиск по regex совпадает (или не совпадает) с текстом. В случае неудачи сообщение об ошибке будет включать шаблон и текст (или шаблон и часть текста, которая неожиданно совпала). regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования с
re.search().Новая в версии 3.1: Добавлено под именем
assertRegexpMatches.Изменено в версии 3.2: Метод
assertRegexpMatches()переименован вassertRegex().Новая в версии 3.2:
assertNotRegex().Новая в версии 3.5: Имя
assertNotRegexpMatchesявляется устаревшим псевдонимом дляassertNotRegex().
-
assertCountEqual(first, second, msg=None) -
Проверка, что последовательность первая содержит те же элементы, что и вторая, независимо от их порядка. Если нет, будет сгенерировано сообщение об ошибке, показывающее различия между последовательностями.
Дублированные элементы не игнорируются при сравнении первой и второй последовательностей. Проверяется, что каждый элемент имеет одинаковое количество в обеих последовательностях. Эквивалентно:
assertEqual(Counter(list(first)), Counter(list(second))), но работает и с последовательностями неизменяемых объектов.Новая в версии 3.2.
Метод
assertEqual()делегирует проверку равенства для объектов одного типа различным методам для разных типов. Эти методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощьюaddTypeEqualityFunc():-
addTypeEqualityFunc(typeobj, function) -
Регистрирует метод для конкретного типа, вызываемый методом
assertEqual()для проверки, сравниваются ли два объекта одного и того же typeobj (а не подклассы) как равные. function должен принимать два позиционных аргумента и необязательный третий аргумент msg=None, как иassertEqual(). Он должен вызывать исключениеself.failureException(msg), когда обнаруживается неравенство между первыми двумя параметрами — возможно, предоставляя полезную информацию и подробно объясняя неравенства в сообщении об ошибке.Новая в версии 3.1.
Список методов для конкретных типов, автоматически используемых методом
assertEqual(), приведен в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать эти методы напрямую.-
Метод
Используется для сравнения
Новый в
строки
3.1
последовательности
3.1
списки
3.1
кортежи
3.1
множества или неизменяемые множества
3.1
словари
3.1
-
assertMultiLineEqual(first, second, msg=None) -
Проверяет, что многострочная строка first равна строке second. Если строки не равны, в сообщении об ошибке будет показан diff (сравнение) двух строк, выделяющий различия. Этот метод используется по умолчанию при сравнении строк с
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 -
Этот атрибут контролирует максимальную длину diff, выводимого методами assert, которые отображают diff при неудаче. По умолчанию значение равно 80*8 символов. Методы assert, на которые влияет этот атрибут, —
assertSequenceEqual()(включая все методы сравнения последовательностей, которые делегируют ему),assertDictEqual()иassertMultiLineEqual().Установка
maxDiffвNoneозначает, что нет максимальной длины diff.Добавлен в версии 3.2.
Фреймворки тестов могут использовать следующие методы для сбора информации о тесте:
-
countTestCases() -
Возвращает количество тестов, представленных этим объектом теста. Для экземпляров
TestCaseэто всегда1.
-
defaultTestResult() -
Возвращает экземпляр класса результатов теста, который должен использоваться для этого класса тестового случая (если другой экземпляр результата не предоставлен методу
run()).Для экземпляров
TestCaseэто всегда будет экземплярTestResult; подклассыTestCaseдолжны переопределять это по мере необходимости.
-
id() -
Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя тестового метода, включая имя модуля и класса.
-
shortDescription() -
Возвращает описание теста или
None, если описание не предоставлено. Стандартная реализация этого метода возвращает первую строку docstring тестового метода, если она доступна, илиNone.Изменено в версии 3.1: В 3.1 это было изменено для добавления имени теста к краткому описанию даже при наличии docstring. Это вызвало проблемы совместимости с расширениями unittest, и добавление имени теста было перенесено в
TextTestResultв Python 3.2.
-
addCleanup(function, *args, **kwargs) -
Добавляет функцию, которая будет вызываться после
tearDown()для очистки ресурсов, используемых во время теста. Функции будут вызываться в обратном порядке к порядку их добавления (LIFO). Они вызываются с любыми аргументами и ключевыми словами, переданными вaddCleanup()при их добавлении.Если
setUp()завершится неудачно, что означает, чтоtearDown()не вызывается, то все добавленные функции очистки всё равно будут вызваны.Добавлен в версии 3.1.
-
-
doCleanups() -
Этот метод вызывается безусловно после
tearDown(), или послеsetUp(), еслиsetUp()вызывает исключение.Он отвечает за вызов всех функций очистки, добавленных с помощью
addCleanup(). Если вам нужно, чтобы функции очистки вызывались доtearDown(), вы можете сами вызватьdoCleanups().doCleanups()извлекает методы из стека функций очистки по одному, поэтому его можно вызвать в любое время.Введено в версии 3.1.
-
-
class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None) -
Этот класс реализует часть интерфейса
TestCase, которая позволяет исполнителю тестов управлять тестом, но не предоставляет методы, которые код теста может использовать для проверки и отчета об ошибках. Это используется для создания тестовых случаев, используя код тестов предыдущих версий, позволяя его интегрировать в фреймворк тестов, основанный наunittest.
Устаревшие алиасы
По историческим причинам, у некоторых методов TestCase было одно или несколько устаревших алиасов. В следующей таблице указаны правильные имена вместе с их устаревшими алиасами:
Имя метода | Устаревший алиас | Устаревший алиас |
|---|---|---|
failUnlessEqual | assertEquals | |
failIfEqual | assertNotEquals | |
failUnless | assert_ | |
failIf | ||
failUnlessRaises | ||
failUnlessAlmostEqual | assertAlmostEquals | |
failIfAlmostEqual | assertNotAlmostEquals | |
assertRegexpMatches | ||
assertNotRegexpMatches | ||
assertRaisesRegexp |
Устарело начиная с версии 3.1: Устарели алиасы fail* в втором столбце.
Устарело начиная с версии 3.2: Устарели алиасы assert* в третьем столбце.
Устарело начиная с версии 3.2: assertRegexpMatches и assertRaisesRegexp были переименованы в assertRegex() и assertRaisesRegex().
Устарело начиная с версии 3.5: Имя assertNotRegexpMatches устарело в пользу assertNotRegex().
Группировка тестов
-
class unittest.TestSuite(tests=()) -
Этот класс представляет собой агрегацию отдельных тестовых случаев и наборов тестов. Класс предоставляет интерфейс, необходимый исполнителю тестов, чтобы он мог выполняться как любой другой тестовый случай. Выполнение экземпляра
TestSuiteэквивалентно итерации по набору, выполняя каждый тест индивидуально.Если заданы тесты, они должны быть итерируемым объектом отдельных тестовых случаев или других наборов тестов, которые будут использоваться для создания набора изначально. Дополнительно предоставляются методы для добавления тестовых случаев и наборов в коллекцию позже.
Объекты
TestSuiteведут себя очень похоже на объектыTestCase, за исключением того, что они фактически не реализуют тест. Вместо этого они используются для агрегирования тестов в группы тестов, которые должны выполняться вместе. Доступны некоторые дополнительные методы для добавления тестов в экземплярыTestSuite:-
addTests(tests) -
Добавить все тесты из итерируемого объекта экземпляров
TestCaseиTestSuiteв этот набор тестов.Это эквивалентно итерации по тестам, вызову
addTest()для каждого элемента.
Следующие методы
TestSuiteсовпадают с методамиTestCase:-
run(result) -
Запустить тесты, связанные с этим набором, собрав результат в объект результатов, переданный как result. Обратите внимание, что в отличие от
TestCase.run(),TestSuite.run()требует передачи объекта результата.
-
debug() -
Запустить тесты, связанные с этим набором, без сбора результатов. Это позволяет исключениям, поднятым тестом, распространяться вызывающей стороне и может использоваться для поддержки запуска тестов в отладчике.
-
countTestCases() -
Возвращает количество тестов, представленных этим тестовым объектом, включая все отдельные тесты и поднаборы.
-
__iter__() -
Тесты, сгруппированные в
TestSuite, всегда доступны для итерации. Подклассы могут лениво предоставлять тесты, переопределяя__iter__(). Обратите внимание, что этот метод может вызываться несколько раз для одного набора (например, при подсчете тестов или сравнении на равенство), поэтому тесты, возвращаемые многократной итерацией доTestSuite.run(), должны быть одинаковыми для каждой итерации вызова. ПослеTestSuite.run(), вызывающие стороны не должны полагаться на тесты, возвращаемые этим методом, если вызывающая сторона не использует подкласс, который переопределяетTestSuite._removeTestAtIndex(), чтобы сохранить ссылки на тесты.Изменено в версии 3.2: В более ранних версиях
TestSuiteнапрямую обращались к тестам, а не через итерацию, поэтому переопределение__iter__()было недостаточно для предоставления тестов.Изменено в версии 3.4: В более ранних версиях
TestSuiteсохранял ссылки на каждыйTestCaseпослеTestSuite.run(). Подклассы могут восстановить это поведение, переопределяяTestSuite._removeTestAtIndex().
В типичном использовании объекта
TestSuiteметодrun()вызываетсяTestRunner, а не конечным тестовым инструментом пользователя. -
Загрузка и выполнение тестов
-
class unittest.TestLoader -
Класс
TestLoaderиспользуется для создания наборов тестов из классов и модулей. Обычно нет необходимости создавать экземпляр этого класса; модульunittestпредоставляет экземпляр, который можно использовать совместно какunittest.defaultTestLoader. Однако использование подкласса или экземпляра позволяет настроить некоторые настраиваемые свойства.Объекты
TestLoaderимеют следующие атрибуты:-
errors -
Список некритичных ошибок, возникших при загрузке тестов. Не сбрасывается загрузчиком в любой момент. Критические ошибки сигнализируются соответствующим методом, вызывающим исключение у вызывающей стороны. Некритические ошибки также указываются синтетическим тестом, который при выполнении поднимет исходную ошибку.
Введено в версии 3.5.
Объекты
TestLoaderимеют следующие методы:-
loadTestsFromTestCase(testCaseClass) -
Возвращает набор всех тестовых случаев, содержащихся в
testCaseClass, производном отTestCase.Экземпляр тестового случая создается для каждого метода, имя которого указано в
getTestCaseNames(). По умолчанию это имена методов, начинающиеся сtest. ЕслиgetTestCaseNames()не возвращает методов, но реализован методrunTest(), вместо этого создается один тестовый случай для этого метода.
-
loadTestsFromModule(module, pattern=None) -
Возвращает набор всех тестовых случаев, содержащихся в заданном модуле. Этот метод ищет в module классы, производные от
TestCase, и создает экземпляр класса для каждого тестового метода, определенного для класса.Примечание
Хотя использование иерархии классов, производных от
TestCase, может быть удобным для совместного использования фикстур и вспомогательных функций, определение тестовых методов в базовых классах, которые не предназначены для прямого создания экземпляров, не сочетается с этим методом. Однако это может быть полезно, когда фикстуры различны и определены в подклассах.Если модуль предоставляет функцию
load_tests, она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это протокол load_tests. Аргумент pattern передается в качестве третьего аргумента вload_tests.Изменено в версии 3.2: Добавлена поддержка
load_tests.Изменено в версии 3.5: Недокументированный и неофициальный аргумент по умолчанию 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, сгенерированному при запуске набора тестов, для целей отчётности; экземплярTestResultвозвращается методомTestRunner.run()для этой цели.Экземпляры
TestResultимеют следующие атрибуты, которые будут полезны при проверке результатов выполнения набора тестов:-
errors -
Список, содержащий 2-кортежи из экземпляров
TestCaseи строк с отформатированными трассировками стека вызовов. Каждый кортеж представляет тест, в котором возникло непредвиденное исключение.
-
failures -
Список, содержащий 2-кортежи из экземпляров
TestCaseи строк с отформатированными трассировками стека вызовов. Каждый кортеж представляет тест, в котором было явно указано о неудаче с использованием методовTestCase.assert*().
-
skipped -
Список, содержащий 2-кортежи из экземпляров
TestCaseи строк, содержащих причину пропуска теста.Добавлена в версии 3.1.
-
expectedFailures -
Список, содержащий 2-кортежи из экземпляров
TestCaseи строк с отформатированными трассировками стека вызовов. Каждый кортеж представляет ожидаемую неудачу тестового случая.
-
unexpectedSuccesses -
Список, содержащий экземпляры
TestCase, которые были помечены как ожидаемые неудачи, но прошли успешно.
-
shouldStop -
Устанавливается в
Trueпри необходимости прервать выполнение тестов с помощьюstop().
-
testsRun -
Общее количество запущенных тестов.
-
buffer -
Если установлено в true,
sys.stdoutиsys.stderrбудут буферизироваться между вызовамиstartTest()иstopTest(). Собраный вывод будет отображён на реальныйsys.stdoutиsys.stderrтолько если тест завершился ошибкой или сбоем. Любой вывод также прикрепляется к сообщению об ошибке/сбое.Добавлена в версии 3.2.
-
failfast -
Если установлено в true,
stop()будет вызван при первой ошибке или сбое, останавливая запуск теста.Добавлена в версии 3.2.
-
tb_locals -
Если установлено в true, локальные переменные будут отображаться в трассировках стека вызовов.
Добавлена в версии 3.5.
-
wasSuccessful() -
Возвращает
Trueесли все запущенные тесты прошли успешно, в противном случае возвращаетFalse.Изменено в версии 3.4: Возвращает
Falseесли были какие-либоunexpectedSuccessesот тестов, помеченных декораторомexpectedFailure().
-
stop() -
Этот метод можно вызвать для сигнализации о необходимости прервать выполнение набора тестов, установив атрибут
shouldStopвTrue. ОбъектыTestRunnerдолжны учитывать этот флаг и возвращаться без выполнения дополнительных тестов.Например, эта функция используется классом
TextTestRunnerдля остановки фреймворка тестов, когда пользователь сигнализирует об прерывании с клавиатуры. Интерактивные инструменты, предоставляющие реализацииTestRunnerмогут использовать это аналогичным образом.
Следующие методы класса
TestResultиспользуются для поддержания внутренних структур данных и могут быть расширены в подклассах для поддержки дополнительных требований к отчётности. Это особенно полезно при создании инструментов, которые поддерживают интерактивную отчётность во время выполнения тестов.-
startTest(test) -
Вызывается, когда тестовый случай test готов к запуску.
-
stopTest(test) -
Вызывается после выполнения тестового случая test, независимо от результата.
-
startTestRun() -
Вызывается один раз перед выполнением любых тестов.
Добавлена в версии 3.1.
-
stopTestRun() -
Вызывается один раз после выполнения всех тестов.
Добавлена в версии 3.1.
-
addError(test, err) -
Вызывается, когда тестовый случай test вызывает непредвиденное исключение. err представляет собой кортеж, возвращаемый
sys.exc_info():(type, value, traceback).По умолчанию добавляет кортеж
(test, formatted_err)в атрибутerrorsэкземпляра, где formatted_err — отформатированная трассировка стека вызовов, полученная из err.
-
addFailure(test, err) -
Вызывается, когда тестовый случай test сигнализирует об ошибке. err представляет собой кортеж, возвращаемый
sys.exc_info():(type, value, traceback).По умолчанию добавляет кортеж
(test, formatted_err)в атрибутfailuresэкземпляра, где formatted_err — отформатированная трассировка стека вызовов, полученная из err.
-
addSuccess(test) -
Вызывается, когда тестовый случай test проходит успешно.
По умолчанию ничего не делает.
-
addSkip(test, reason) -
Вызывается, когда тестовый случай test пропущен. reason — причина пропуска теста.
По умолчанию добавляет кортеж
(test, reason)в атрибутskippedэкземпляра.
-
addExpectedFailure(test, err) -
Вызывается, когда тестовый случай test завершился ошибкой, но был помечен декоратором
expectedFailure().По умолчанию добавляет кортеж
(test, formatted_err)в атрибутexpectedFailuresэкземпляра, где formatted_err — отформатированная трассировка стека вызовов, полученная из 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):
# 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: Поиск больше не проверяет имена пакетов на соответствие шаблону из-за невозможности соответствия имен пакетов по умолчанию шаблону.
Фикстуры классов и модулей
Фикстуры уровня класса и модуля реализованы в TestSuite. Когда набор тестов сталкивается с тестом из нового класса, то tearDownClass() из предыдущего класса (если он есть) вызывается, за которым следует setUpClass() из нового класса.
Аналогично, если тест принадлежит другому модулю, чем предыдущий тест, то tearDownModule из предыдущего модуля выполняется, за которым следует setUpModule из нового модуля.
После выполнения всех тестов выполняются финальные tearDownClass и tearDownModule.
Обратите внимание, что общие фикстуры не сочетаются с такими [потенциальными] функциями, как распараллеливание тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.
По умолчанию порядок тестов, созданных загрузчиками тестов unittest, состоит в том, чтобы группировать все тесты из одного модуля и одного класса вместе. Это приведет к тому, что setUpClass / setUpModule (и т. д.) будут вызываться ровно один раз на класс и модуль. Если вы случайным образом меняете порядок, так что тесты из разных модулей и классов располагаются рядом друг с другом, то эти общие функции фикстур могут вызываться несколько раз в одном запуске теста.
Общие фикстуры не предназначены для работы с наборами тестов с нестандартным порядком. Для фреймворков, которые не хотят поддерживать общие фикстуры, всё ещё существует BaseTestSuite.
Если при выполнении одной из общих функций фикстур возникает исключение, тест считается ошибкой. Поскольку нет соответствующей экземпляра теста, создается объект _ErrorHolder (который имеет тот же интерфейс, что и TestCase) для обозначения ошибки. Если вы просто используете стандартный запуск тестов unittest, эта деталь не имеет значения, но если вы создаёте фреймворк, она может быть важной.
setUpClass и tearDownClass
Они должны быть реализованы как методы класса:
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()
Если вы хотите, чтобы setUpClass и tearDownClass в базовых классах вызывались, то вы должны вызвать их сами. Реализации в TestCase пустые.
Если при выполнении setUpClass возникает исключение, то тесты в классе не выполняются, и tearDownClass не выполняется. Пропущенные классы не будут иметь setUpClass или tearDownClass выполнение. Если исключение является исключением SkipTest, то класс будет отмечен как пропущенный, а не как ошибочный.
setUpModule и tearDownModule
Они должны быть реализованы как функции:
def setUpModule():
createConnection()
def tearDownModule():
closeConnection()
Если при выполнении setUpModule возникает исключение, то ни один из тестов в модуле не будет выполнен, и tearDownModule не будет выполнен. Если исключение является исключением SkipTest, то модуль будет отмечен как пропущенный, а не как ошибочный.
Обработка сигналов
Новое в версии 3.2.
Командная опция -c/--catch для unittest, а также параметр catchbreak к unittest.main(), обеспечивают более дружелюбную обработку нажатия Ctrl+C во время выполнения теста. При включенном поведении перехвата Ctrl+C позволяет текущему выполняющемуся тесту завершиться, а затем выполнение теста завершается и сообщает обо всех результатах до этого момента. Второе нажатие Ctrl+C вызовет KeyboardInterrupt обычным способом.
Обработчик сигналов для обработки Ctrl+C пытается оставаться совместимым с кодом или тестами, которые устанавливают свои собственные обработчики signal.SIGINT. Если обработчик unittest вызывается, но не является установленным обработчиком signal.SIGINT, т. е. он был заменен системой и делегирован, то он вызывает обработчик по умолчанию. Это обычно ожидаемое поведение кода, который заменяет установленный обработчик и делегирует его. Для отдельных тестов, которым нужно unittest отключить обработку нажатия Ctrl+C, можно использовать декоратор removeHandler().
Существует несколько служебных функций для авторов фреймворков, чтобы включить функциональность обработки нажатия Ctrl+C в рамках тестов.
-
unittest.installHandler() -
Установить обработчик Ctrl+C. При получении сигнала
signal.SIGINT(обычно в ответ на нажатие пользователем Ctrl+C) у всех зарегистрированных результатов вызываетсяstop().
-
unittest.registerResult(result) -
Зарегистрировать объект
TestResultдля обработки нажатия Ctrl+C. Регистрация результата сохраняет слабую ссылку на него, поэтому она не препятствует сбору мусора результата.Регистрация объекта
TestResultне имеет побочных эффектов, если обработка нажатия Ctrl+C не включена, поэтому фреймворки тестов могут безусловно регистрировать все созданные результаты независимо от того, включена ли обработка.
-
unittest.removeResult(result) -
Удалить зарегистрированный результат. После удаления результата
stop()больше не будет вызываться на этом объекте результата в ответ на нажатие Ctrl+C.
-
unittest.removeHandler(function=None) -
При вызове без аргументов эта функция удаляет обработчик Ctrl+C, если он был установлен. Эта функция также может использоваться в качестве декоратора для тестов, чтобы временно удалить обработчик во время выполнения теста:
@unittest.removeHandler def test_signal_handling(self): ...
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.7/library/unittest.html