Spec-Zone.ru › Python 3.10

unittest — Фреймворк для юнит-тестирования

Исходный код: Lib/unittest/__init__.py

(Если вы уже знакомы с основными понятиями тестирования, можете перейти к списку методов assert.)

Фреймворк для юнит-тестирования unittest первоначально был вдохновлён JUnit и имеет схожую структуру с основными фреймворками юнит-тестирования на других языках. Он поддерживает автоматизацию тестов, совместное использование кода подготовки и завершения для тестов, агрегацию тестов в коллекции и независимость тестов от фреймворка отчётности.

Для достижения этого, фреймворк unittest поддерживает некоторые важные концепции объектно-ориентированным способом:

тестовый фикстур

Тестовый фикстур представляет подготовку, необходимую для выполнения одного или нескольких тестов, а также любые связанные действия по очистке. Это может включать, например, создание временных или прокси-баз данных, каталогов или запуск процесса сервера.

тестовый случай

Тестовый случай — это отдельная единица тестирования. Он проверяет определённый ответ на конкретный набор входных данных. unittest предоставляет базовый класс TestCase, который можно использовать для создания новых тестовых случаев.

тестовый набор

Тестовый набор — это коллекция тестовых случаев, тестовых наборов или обоих. Он используется для агрегации тестов, которые должны быть выполнены вместе.

тестовый рантаймер

Тестовый рантаймер — это компонент, который организует выполнение тестов и предоставляет результат пользователю. Рантаймер может использовать графический интерфейс, текстовый интерфейс или возвращать специальное значение для указания результатов выполнения тестов.

См. также

Module doctest

Другой модуль поддержки тестов с совершенно другим подходом.

Simple Smalltalk Testing: With Patterns

Оригинальная статья Кента Бека о фреймворках тестирования, использующих шаблон, используемый в unittest.

pytest

Фреймворк юнит-тестирования сторонних разработчиков с более лёгким синтаксисом для написания тестов. Например, 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'])
        # 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.

Если у вас есть пакет, установленный глобально, и вы пытаетесь произвести обнаружение тестов на другой копии пакета, то импорт может произойти из неправильного места. Если это произойдёт, обнаружение тестов выведет предупреждение и завершит работу.

Если вы указываете начальный каталог как имя пакета, а не путь к каталогу, то обнаружение предполагает, что любая расположение, с которого производится импорт, является предполагаемым вами, поэтому предупреждение не будет выведено.

Тестовые модули и пакеты могут настраивать загрузку и обнаружение тестов с помощью протокола загрузки тестов.

Изменено в версии 3.4: Обнаружение тестов поддерживает пакеты имён пространств для начального каталога. Обратите внимание, что вам также необходимо указать каталог верхнего уровня (например, python -m unittest discover -s root/namespace -t root).

Организация тестового кода

Основными строительными блоками модульного тестирования являются тестовые случаи — отдельные сценарии, которые необходимо настроить и проверить на корректность. В unittest, тестовые случаи представлены экземплярами unittest.TestCase. Чтобы создать собственные тестовые случаи, необходимо написать подклассы TestCase или использовать FunctionTestCase.

Тестовый код экземпляра TestCase должен быть полностью самодостаточным, чтобы его можно было запускать изолированно или в произвольной комбинации с любым количеством других тестовых случаев.

Простейший подкласс TestCase просто реализует тестовый метод (т. е. метод, имя которого начинается с test) для выполнения определенного тестового кода:

import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
    def test_default_widget_size(self):
        widget = Widget('The widget')
        self.assertEqual(widget.size(), (50, 50))

Обратите внимание, что для тестирования чего-либо используется один из методов assert*() , предоставляемых базовым классом TestCase. Если тест завершается неудачей, будет поднято исключение с объяснительным сообщением, и unittest идентифицирует тестовый случай как неудачу. Любые другие исключения будут обрабатываться как ошибки.

Тестов может быть много, и их настройка может повторяться. К счастью, мы можем вынести код настройки, реализовав метод с именем setUp(), который тестовый фреймворк автоматически вызовет для каждого выполняемого теста:

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def test_default_widget_size(self):
        self.assertEqual(self.widget.size(), (50,50),
                         'incorrect default size')

    def test_widget_resize(self):
        self.widget.resize(100,150)
        self.assertEqual(self.widget.size(), (100,150),
                         'wrong size after resize')

Примечание

Порядок выполнения различных тестов определяется сортировкой имён тестовых методов относительно встроенного порядка строк.

Если метод setUp() генерирует исключение во время выполнения теста, фреймворк сочтёт тест ошибочным, и тестовый метод не будет выполнен.

Аналогично, мы можем предоставить метод tearDown() для завершения работы после выполнения тестового метода:

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def tearDown(self):
        self.widget.dispose()

Если метод setUp() выполнился успешно, метод tearDown() будет выполнен независимо от того, выполнился ли тестовый метод успешно или нет.

Такая рабочая среда для тестового кода называется тестовым фикстуром. Новый экземпляр TestCase создается как уникальный тестовый фикстур, используемый для выполнения каждого отдельного тестового метода. Таким образом, setUp(), tearDown(), и __init__() будут вызываться один раз на тест.

Рекомендуется использовать реализации TestCase для группировки тестов по функциям, которые они тестируют. unittest предоставляет механизм для этого: тестовый набор, представленный классом unittest’s TestSuite. В большинстве случаев вызов unittest.main() сделает все правильно, собрав все тестовые случаи модуля и выполнив их.

Однако, если вы хотите настроить создание тестового набора, вы можете сделать это самостоятельно:

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('test_default_widget_size'))
    suite.addTest(WidgetTestCase('test_widget_resize'))
    return suite

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())

Определения тестовых случаев и тестовых наборов можно размещать в тех же модулях, что и код, который они должны тестировать (например, widget.py), но есть несколько преимуществ размещения тестового кода в отдельном модуле, например, test_widget.py:

  • Модуль тестов можно запускать автономно из командной строки.
  • Тестовый код легче отделить от кода, который распространяется.
  • Существует меньше соблазна изменять тестовый код, чтобы он соответствовал тестируемому коду без веских оснований.
  • Тестовый код следует изменять значительно реже, чем код, который он тестирует.
  • Тестируемый код можно легче перерабатывать.
  • Тесты для модулей, написанных на C, должны быть в отдельных модулях, так почему бы не быть последовательными?
  • Если стратегия тестирования меняется, нет необходимости изменять исходный код.

Переиспользование старого тестового кода

Некоторые пользователи могут обнаружить, что у них есть существующий тестовый код, который они хотели бы запускать из unittest, не преобразовывая каждый старый тестовый метод в подкласс TestCase.

По этой причине unittest предоставляет класс FunctionTestCase. Этот подкласс TestCase может использоваться для обертывания существующей тестовой функции. Также можно предоставить функции настройки и завершения.

Учитывая следующую тестовую функцию:

def testSomething():
    something = makeSomething()
    assert something.name is not None
    # ...

можно создать эквивалентный экземпляр тестового случая следующим образом, с необязательными методами настройки и завершения:

testcase = unittest.FunctionTestCase(testSomething,
                                     setUp=makeSomethingDB,
                                     tearDown=deleteSomethingDB)

Примечание

Несмотря на то, что FunctionTestCase можно использовать для быстрого перевода существующей тестовой базы в систему на основе unittest, этот подход не рекомендуется. Выделение времени на создание надлежащих подклассов TestCase сделает будущие рефакторинги тестов намного проще.

В некоторых случаях существующие тесты могут быть написаны с использованием модуля doctest. Если это так, doctest предоставляет класс DocTestSuite, который может автоматически создавать экземпляры unittest.TestSuite из существующих тестов на основе doctest.

Пропуск тестов и ожидаемые ошибки

Новая в версии 3.1.

Unittest поддерживает пропуск отдельных тестовых методов и даже целых классов тестов. Кроме того, он поддерживает пометку теста как «ожидаемой ошибки» — это тест, который сломан и даст сбой, но не должен учитываться как сбой в TestResult.

Пропуск теста осуществляется просто с помощью skip() декоратора или одного из его условных вариантов, вызова TestCase.skipTest() внутри setUp() или тестового метода, или поднятия SkipTest непосредственно.

Базовый пропуск выглядит так:

class MyTestCase(unittest.TestCase):

    @unittest.skip("demonstrating skipping")
    def test_nothing(self):
        self.fail("shouldn't happen")

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # windows specific testing code
        pass

    def test_maybe_skipped(self):
        if not external_resource_available():
            self.skipTest("external resource not available")
        # test code that depends on the external resource
        pass

Это вывод выполнения примера выше в режиме подробной информации:

test_format (__main__.MyTestCase) ... 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 предоставляет несколько методов утверждений для проверки и отчёта о сбоях. В следующей таблице перечислены наиболее часто используемые методы (см. таблицы ниже для получения более подробной информации о методах утверждений):

Метод

Проверяет, что

Введено в

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

Все методы утверждений принимают аргумент 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.

Также возможно проверить возникновение исключений, предупреждений и сообщений в журнал, используя следующие методы:

Метод

Проверяет, что

Введено в

assertRaises(exc, fun, *args, **kwds)

fun(*args, **kwds) вызывает exc

assertRaisesRegex(exc, r, fun, *args, **kwds)

fun(*args, **kwds) вызывает exc и сообщение соответствует регулярному выражению r

3.1

assertWarns(warn, fun, *args, **kwds)

fun(*args, **kwds) вызывает warn

3.2

assertWarnsRegex(warn, r, fun, *args, **kwds)

fun(*args, **kwds) вызывает warn и сообщение соответствует регулярному выражению r

3.2

assertLogs(logger, level)

Блок with записывает в журнал logger с минимальным уровнем level

3.4

assertNoLogs(logger, level)

The with block does not log on

logger с минимальным уровнем level

3.10

assertRaises(exception, callable, *args, **kwds)
assertRaises(exception, *, msg=None)

Проверка, что исключение возникает при вызове callable с любыми позиционными или ключевыми аргументами, которые также передаются в assertRaises(). Тест проходит, если exception возникает, является ошибкой, если возникает другое исключение, или терпит неудачу, если исключение не возникает. Для перехвата любой группы исключений можно передать кортеж содержащий классы исключений как exception.

Если заданы только аргументы exception и, возможно, msg, возвращается менеджер контекста, чтобы код, который тестируется, можно было написать встроеным образом, а не как функцию:

with self.assertRaises(SomeException):
    do_something()

При использовании в качестве менеджера контекста, assertRaises() принимает дополнительный ключевой аргумент msg.

Менеджер контекста будет хранить пойманный объект исключения в своем exception атрибуте. Это может быть полезно, если нужно выполнить дополнительные проверки на поднятом исключении:

with self.assertRaises(SomeException) as cm:
    do_something()

the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)

Изменено в версии 3.1: Добавлена возможность использования assertRaises() в качестве менеджера контекста.

Изменено в версии 3.2: Добавлен атрибут exception.

Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.

assertRaisesRegex(exception, regex, callable, *args, **kwds)
assertRaisesRegex(exception, regex, *, msg=None)

Как assertRaises(), но также проверяет, что regex соответствует строковому представлению поднятого исключения. regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования с re.search(). Примеры:

self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$",
                       int, 'XYZ')

или:

with self.assertRaisesRegex(ValueError, 'literal'):
   int('XYZ')

Введено в версии 3.1: Добавлен под названием assertRaisesRegexp.

Изменено в версии 3.2: Переименовано в assertRaisesRegex().

Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.

assertWarns(warning, callable, *args, **kwds)
assertWarns(warning, *, msg=None)

Проверка, что предупреждение вызывается, когда callable вызывается с любыми позиционными или ключевыми аргументами, которые также передаются в assertWarns(). Тест проходит, если warning сгенерировано и терпит неудачу, если нет. Любое исключение является ошибкой. Для перехвата любой группы предупреждений можно передать кортеж, содержащий классы предупреждений как warnings.

Если заданы только аргументы warning и, возможно, msg, возвращается менеджер контекста, чтобы код, который тестируется, можно было написать встроеным образом, а не как функцию:

with self.assertWarns(SomeWarning):
    do_something()

При использовании в качестве менеджера контекста, assertWarns() принимает дополнительный ключевой аргумент msg.

Менеджер контекста сохранит пойманный объект предупреждения в своем warning атрибуте и строку источника, которая вызвала предупреждение, в filename и lineno атрибутах. Это может быть полезно, если нужно выполнить дополнительные проверки на пойманном предупреждении:

with self.assertWarns(SomeWarning) as cm:
    do_something()

self.assertIn('myfile.py', cm.filename)
self.assertEqual(320, cm.lineno)

Этот метод работает независимо от фильтров предупреждений, установленных во время его вызова.

Введено в версии 3.2.

Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.

assertWarnsRegex(warning, regex, callable, *args, **kwds)
assertWarnsRegex(warning, regex, *, msg=None)

Подобно assertWarns(), но также проверяет, что regex соответствует сообщению сгенерированного предупреждения. regex может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, подходящее для использования с re.search(). Пример:

self.assertWarnsRegex(DeprecationWarning,
                      r'legacy_function\(\) is deprecated',
                      legacy_function, 'XYZ')

или:

with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):
    frobnicate('/etc/passwd')

Новая функция в версии 3.2.

Изменено в версии 3.3: Добавлен ключевой аргумент msg при использовании в качестве менеджера контекста.

assertLogs(logger=None, level=None)

Менеджер контекста для проверки того, что по крайней мере одно сообщение зарегистрировано в logger или одном из его дочерних логгеров, с указанным level.

Если задано, logger должен быть объектом logging.Logger или строкой, содержащей имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения, не заблокированные дочерним логгером, который не поддерживает распространение.

Если задано, level должен быть либо числовым уровнем логирования, либо его строковым эквивалентом (например, либо "ERROR" либо logging.ERROR). По умолчанию logging.INFO.

Тест пройден, если по крайней мере одно сообщение, выпущенное внутри блока with , соответствует условиям logger и level; в противном случае тест провален.

Объект, возвращаемый менеджером контекста, — это вспомогательный объект записи, который отслеживает соответствующие сообщения в логах. У него есть два атрибута:

records

Список объектов logging.LogRecord соответствующих сообщений в логах.

output

Список объектов 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.

assertNoLogs(logger=None, level=None)

Менеджер контекста для проверки того, что сообщения не регистрируются в logger или одном из его дочерних логгеров, с указанным level.

Если задано, logger должен быть объектом logging.Logger или строкой, содержащей имя логгера. По умолчанию используется корневой логгер, который перехватывает все сообщения.

Если задано, level должен быть либо числовым уровнем логирования, либо его строковым эквивалентом (например, либо "ERROR" либо logging.ERROR). По умолчанию logging.INFO.

В отличие от assertLogs(), менеджер контекста ничего не вернет.

Новая функция в версии 3.10.

Существуют и другие методы для более точной проверки, такие как:

Метод

Проверяет

В версии

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 приблизительно (или не приблизительно) равны, вычисляя разницу, округляя до заданного количества десятичных знаков (по умолчанию 7) и сравнивая с нулем. Обратите внимание, что эти методы округляют значения до заданного количества десятичных знаков (как функция round()), а не значимых цифр.

Если вместо places задан delta, то разница между first и second должна быть меньше или равна (или больше) delta.

Задавать одновременно delta и places приведёт к ошибке TypeError.

Изменено в версии 3.2: assertAlmostEqual() автоматически считает объекты приблизительно равными, если они сравниваются как равные. assertNotAlmostEqual() автоматически завершается ошибкой, если объекты сравниваются как равные. Добавлен ключевой аргумент delta.

assertGreater(first, second, msg=None)
assertGreaterEqual(first, second, msg=None)
assertLess(first, second, msg=None)
assertLessEqual(first, second, msg=None)

Проверка того, что first соответственно >, >=, < или <= second в зависимости от имени метода. Если нет, тест провален:

>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"

Новая функция в версии 3.1.

assertRegex(text, regex, msg=None)
assertNotRegex(text, regex, msg=None)

Проверка того, что поиск по regex соответствует (или не соответствует) 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():

END_OF_DOCUMENT_MARKER
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 символов. Методы assert, затронутые этим атрибутом, — assertSequenceEqual() (включая все методы сравнения последовательностей, которые делегируют ему), assertDictEqual() и assertMultiLineEqual().

Установление значения maxDiff в None означает, что нет максимальной длины различий.

Введено в версии 3.2.

Тестовые структуры могут использовать следующие методы для сбора информации о тесте:

countTestCases()

Возвращает количество тестов, представленных этим объектом теста. Для экземпляров TestCase это всегда 1.

defaultTestResult()

Возвращает экземпляр класса результатов теста, который должен использоваться для этого класса тестового случая (если другой экземпляр результатов не предоставлен методу run()).

Для экземпляров TestCase это всегда будет экземпляр TestResult; подклассы TestCase должны переопределять это при необходимости.

id()

Возвращает строку, идентифицирующую конкретный тестовый случай. Обычно это полное имя метода теста, включая имя модуля и класса.

shortDescription()

Возвращает описание теста или None если описание не предоставлено. Реализация по умолчанию возвращает первую строку документации метода теста, если она доступна, или None.

Изменено в версии 3.1: В 3.1 это было изменено для добавления имени теста в краткое описание даже при наличии документации. Это вызвало проблемы совместимости с расширениями unittest, и добавление имени теста было перенесено в TextTestResult в Python 3.2.

addCleanup(function, /, *args, **kwargs)

Добавить функцию, которая будет вызвана после tearDown() для очистки ресурсов, используемых во время теста. Функции будут вызваны в обратном порядке к порядку их добавления (LIFO). Они вызываются с любыми аргументами и именованными аргументами, переданными в addCleanup() при их добавлении.

Если setUp() завершится ошибкой, что означает, что tearDown() не будет вызван, любые добавленные функции очистки всё равно будут вызваны.

Новая в версии 3.1.

doCleanups()

Этот метод вызывается безусловно после tearDown() или после setUp(), если setUp() вызывает исключение.

Он отвечает за вызов всех функций очистки, добавленных с помощью addCleanup(). Если вам нужно, чтобы функции очистки вызывались до tearDown(), вы можете вызвать doCleanups() самостоятельно.

doCleanups() извлекает методы из стека функций очистки по одному, поэтому его можно вызвать в любое время.

Новая в версии 3.1.

classmethod addClassCleanup(function, /, *args, **kwargs)

Добавить функцию, которая будет вызвана после tearDownClass() для очистки ресурсов, используемых в классе тестов. Функции будут вызваны в обратном порядке к порядку их добавления (LIFO). Они вызываются с любыми аргументами и именованными аргументами, переданными в addClassCleanup() при их добавлении.

Если setUpClass() завершится ошибкой, что означает, что tearDownClass() не будет вызван, любые добавленные функции очистки всё равно будут вызваны.

Новая в версии 3.8.

classmethod doClassCleanups()

Этот метод вызывается безусловно после tearDownClass() или после setUpClass(), если setUpClass() вызывает исключение.

Он отвечает за вызов всех функций очистки, добавленных с помощью addClassCleanup(). Если вам нужно, чтобы функции очистки вызывались до tearDownClass(), вы можете вызвать doClassCleanups() самостоятельно.

doClassCleanups() извлекает методы из стека функций очистки по одному, поэтому его можно вызвать в любое время.

Новая в версии 3.8.

class unittest.IsolatedAsyncioTestCase(methodName='runTest')

Этот класс предоставляет API, аналогичный TestCase, и также принимает корутины в качестве функций тестов.

Новая в версии 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"].

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:

addTest(test)

Добавить 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)

Возвращает набор всех тестовых случаев, содержащихся в заданном модуле. Этот метод ищет в модуле классы, производные от TestCase, и создает экземпляр класса для каждого тестового метода, определенного для класса.

Примечание

Хотя использование иерархии классов, производных от TestCase, может быть удобным для совместного использования фикстур и вспомогательных функций, определение тестовых методов в базовых классах, которые не предполагается непосредственно использовать, не работает с этим методом. Однако это может быть полезно, когда фикстуры отличаются и определены в подклассах.

Если модуль предоставляет функцию load_tests , она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это протокол load_tests. Аргумент шаблон передается в качестве третьего аргумента в load_tests.

Изменено в версии 3.2: Добавлена поддержка load_tests.

Изменено в версии 3.5: Недокументированный и неофициальный аргумент по умолчанию use_load_tests устарел и игнорируется, хотя он по-прежнему принимается для обратной совместимости. Метод также теперь принимает аргумент только с ключевыми словами шаблон, который передается в load_tests как третий аргумент.

loadTestsFromName(name, module=None)

Возвращает набор всех тестовых случаев, заданных строковым спецификатором.

Спецификатор имя представляет собой «точку с запятой», которая может ссылаться на модуль, класс тестового случая, тестовый метод внутри класса тестового случая, экземпляр TestSuite или вызываемый объект, который возвращает экземпляр TestCase или TestSuite.

Например, если у вас есть модуль SampleTests содержащий производный от TestCase класс SampleTestCase с тремя тестовыми методами (test_one(), test_two(), и test_three()), спецификатор 'SampleTests.SampleTestCase' приведет к тому, что этот метод вернет набор, который запустит все три тестовых метода. Использование спецификатора 'SampleTests.SampleTestCase.test_two' приведет к возвращению набора тестов, который запустит только тестовый метод test_two().

Метод может по желанию разрешать имя относительно данного модуля.

Изменено в версии 3.5: Если во время обхода имя возникает ImportError или AttributeError, то будет возвращен синтетический тест, который при запуске поднимет эту ошибку. Эти ошибки включаются в накопленные ошибки self.errors.

loadTestsFromNames(names, module=None)

Аналогично loadTestsFromName(), но принимает последовательность имен вместо одного имени. Возвращаемое значение — набор тестов, поддерживающий все тесты, определенные для каждого имени.

getTestCaseNames(testCaseClass)

Возвращает отсортированную последовательность имен методов, найденных в testCaseClass; это должен быть подкласс TestCase.

discover(start_dir, pattern='test*.py', top_level_dir=None)

Найдите все тестовые модули, рекурсивно пройдя по подкаталогам из указанной начальной директории, и верните объект TestSuite, содержащий их. Будут загружены только те тестовые файлы, которые соответствуют шаблону. (Используется синтаксис шаблонов в стиле оболочки.) Будут загружены только имена модулей, которые могут быть импортированы (т.е. являются допустимыми идентификаторами Python).

Все тестовые модули должны быть импортируемы с верхнего уровня проекта. Если начальная директория не является директорией верхнего уровня, то директория верхнего уровня должна быть указана отдельно.

Если импорт модуля завершается ошибкой, например, из-за синтаксической ошибки, то это будет записано как одна ошибка, и поиск продолжит выполняться. Если ошибка импорта вызвана поднятием SkipTest, она будет записана как пропуск, а не ошибка.

Если найден пакет (каталог, содержащий файл, имя которого __init__.py), пакет будет проверен на наличие функции load_tests. Если она существует, то она будет вызвана package.load_tests(loader, tests, pattern). Поиск тестов позаботится о том, чтобы пакет проверялся на наличие тестов только один раз во время вызова, даже если функция load_tests сама вызывает loader.discover.

Если load_tests существует, то поиск не рекурсивно входит в пакет, load_tests отвечает за загрузку всех тестов в пакете.

Шаблон намеренно не хранится в качестве атрибута загрузчика, чтобы пакеты могли продолжить поиск сами. top_level_dir хранится, чтобы load_tests не нужно было передавать этот аргумент в loader.discover().

start_dir может быть именем модуля с точкой, а также каталогом.

Введено в версии 3.2.

Изменено в версии 3.4: Модули, которые поднимают SkipTest при импорте, регистрируются как пропуски, а не ошибки.

Изменено в версии 3.4: start_dir может быть пространством имен пакетов.

Изменено в версии 3.4: Пути сортируются перед импортом, чтобы порядок выполнения был одинаковым, даже если порядок в файловой системе не зависит от имени файла.

Изменено в версии 3.5: Найденные пакеты теперь проверяются на наличие load_tests независимо от того, соответствует ли их путь шаблону, потому что невозможно, чтобы имя пакета соответствовало шаблону по умолчанию.

Следующие атрибуты TestLoader можно настроить, используя наследование или присвоение экземпляру:

testMethodPrefix

Строка, задающая префикс имен методов, которые будут интерпретироваться как тестовые методы. Значение по умолчанию — 'test'.

Это влияет на getTestCaseNames() и все методы loadTestsFrom*().

sortTestMethodsUsing

Функция, используемая для сравнения имен методов при сортировке в getTestCaseNames() и во всех методах loadTestsFrom*().

suiteClass

Вызываемый объект, который строит набор тестов из списка тестов. Методы на результирующем объекте не требуются. Значение по умолчанию — класс TestSuite.

Это влияет на все методы loadTestsFrom*().

testNamePatterns

Список шаблонов имён тестов в стиле оболочки Unix, которым должны соответствовать методы тестов, чтобы быть включёнными в наборы тестов (см. опцию -k).

Если этот атрибут не None (значение по умолчанию), все методы тестов, которые должны быть включены в наборы тестов, должны соответствовать одному из шаблонов в этом списке. Обратите внимание, что соответствие всегда выполняется с помощью fnmatch.fnmatchcase(), поэтому, в отличие от шаблонов, переданных в опцию -k, простые шаблоны подстрок должны быть преобразованы с использованием * шаблонов.

Это влияет на все методы loadTestsFrom*().

New in version 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(), и тесты выполняются, а результаты выводятся в stdout.

unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None)

Программа командной строки, загружающая набор тестов из 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: Обнаружение больше не проверяет имена пакетов на соответствие pattern из-за невозможности совпадения имен пакетов с шаблоном по умолчанию.

Фикстуры классов и модулей

Фикстуры на уровне класса и модуля реализованы в TestSuite. Когда тестовый набор встречает тест из нового класса, tearDownClass() предыдущего класса (если он есть) вызывается, за которым следует setUpClass() нового класса.

Аналогично, если тест из другого модуля, чем предыдущий тест, то tearDownModule предыдущего модуля выполняется, за которым следует setUpModule нового модуля.

После выполнения всех тестов выполняются заключительные tearDownClass и tearDownModule.

Обратите внимание, что общие фикстуры плохо взаимодействуют с [возможными] функциями, такими как распараллеливание тестов, и нарушают изоляцию тестов. Их следует использовать с осторожностью.

По умолчанию тесты, созданные загрузчиками тестов unittest, группируются вместе по модулям и классам. Это приведет к тому, что setUpClass / setUpModule (и т. д.) будут вызваны ровно один раз на класс и модуль. Если вы рандомизируете порядок, так что тесты из разных модулей и классов расположены рядом друг с другом, то эти общие функции фикстуры могут вызываться несколько раз в одном запуске тестов.

Общие фикстуры не предназначены для работы с наборами с нестандартным порядком. Для фреймворков, не желающих поддерживать общие фикстуры, все еще существует BaseTestSuite.

Если при выполнении одной из общих функций фикстуры возникает исключение, тест регистрируется как ошибка. Поскольку нет соответствующего экземпляра теста, создается объект _ErrorHolder (который имеет тот же интерфейс, что и TestCase) для представления ошибки. Если вы просто используете стандартный исполняемый файл тестов unittest, эта деталь не имеет значения, но если вы автор фреймворка, она может быть важна.

setUpClass и tearDownClass

Эти методы должны быть реализованы как методы класса:

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()

Если вам нужны setUpClass и tearDownClass для базовых классов, то вы должны вызвать их сами. Реализации в TestCase пустые.

Если во время setUpClass возникает исключение, тесты в классе не выполняются, и tearDownClass не выполняется. Для пропущенных классов setUpClass и tearDownClass не будут выполняться. Если исключение является исключением SkipTest, то класс будет зарегистрирован как пропущенный, а не как ошибка.

setUpModule и tearDownModule

Эти методы должны быть реализованы как функции:

def setUpModule():
    createConnection()

def tearDownModule():
    closeConnection()

Если в setUpModule возникает исключение, то тесты в модуле не выполняются, и tearDownModule не выполняется. Если исключение является исключением SkipTest, то модуль будет зарегистрирован как пропущенный, а не как ошибка.

Чтобы добавить код очистки, который должен выполняться даже в случае исключения, используйте addModuleCleanup:

unittest.addModuleCleanup(function, /, *args, **kwargs)

Добавляет функцию, которая будет вызываться после tearDownModule() для очистки ресурсов, используемых во время класса теста. Функции будут вызываться в обратном порядке к порядку их добавления (LIFO). Они вызываются с любыми аргументами и ключевыми аргументами, переданными в addModuleCleanup() при их добавлении.

Если setUpModule() завершается неудачно, что означает, что tearDownModule() не вызывается, то любые добавленные функции очистки все равно будут вызваны.

Введено в версии 3.8.

unittest.doModuleCleanups()

Эта функция вызывается безусловно после tearDownModule(), или после setUpModule() если setUpModule() вызывает исключение.

Она отвечает за вызов всех функций очистки, добавленных addModuleCleanup(). Если вам нужны функции очистки, чтобы вызываться *до* tearDownModule(), то вы можете сами вызвать doModuleCleanups().

doModuleCleanups() извлекает методы из стека функций очистки по одному за раз, поэтому ее можно вызывать в любое время.

Введено в версии 3.8.

Обработка сигналов

Новая версия 3.2.

Командная строка опция -c/--catch для unittest, а также параметр catchbreak к unittest.main(), обеспечивают более удобную обработку нажатия Ctrl+C во время выполнения теста. При включенном поведении перехвата прерывания, нажатие Ctrl+C позволит текущему выполняемому тесту завершиться, а затем выполнение теста закончится и будут отображены все результаты до этого момента. Второе нажатие Ctrl+C сгенерирует KeyboardInterrupt стандартным способом.

Обработчик сигнала для обработки Ctrl+C пытается сохранить совместимость с кодом или тестами, которые устанавливают собственный обработчик signal.SIGINT. Если обработчик unittest вызывается, но не является установленным обработчиком signal.SIGINT, т.е. он был заменён тестируемой системой и делегирован, то вызывается обработчик по умолчанию. Это обычно ожидаемое поведение кода, который заменяет установленный обработчик и делегирует ему. Для отдельных тестов, которым требуется 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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/unittest.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API