Spec-Zone.ru › Python 3.13

unittest — Фреймворк для модульного тестирования

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

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

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

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

Фикстура теста

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

Тест-кейс

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

Набор тестов

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

Запускатель тестов

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

См. также

Module doctest

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

Простой тест Smalltalk: С шаблонами

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

pytest

Фреймворк для модульного тестирования стороннего разработчика с более лёгким синтаксисом для написания тестов. Например, assert func(10) == 42.

Классификация инструментов тестирования Python

Расширенный список инструментов тестирования Python, включая фреймворки функционального тестирования и библиотеки объектов-заглушек.

Список рассылки по тестированию в Python

Группа специального интереса для обсуждения тестирования и инструментов тестирования в Python.

Скрипт Tools/unittestgui/unittestgui.py в дистрибутиве исходного кода Python — это инструмент графического интерфейса для обнаружения и выполнения тестов. Он предназначен в основном для удобства использования для тех, кто только начинает работать с модульным тестированием. Для производственных сред рекомендуется использовать систему непрерывной интеграции, такую как Buildbot, Jenkins, GitHub Actions или AppVeyor.

Базовый пример

Модуль unittest предоставляет богатый набор инструментов для построения и запуска тестов. Этот раздел демонстрирует, что небольшого подмножества инструментов достаточно для удовлетворения потребностей большинства пользователей.

Вот небольшой скрипт для тестирования трёх методов строк:

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

Тест-кейс создаётся путём наследования класса unittest.TestCase. Три отдельных теста определяются методами, имена которых начинаются с букв test. Эта соглашение об именовании сообщает запускателю тестов, какие методы представляют собой тесты.

Суть каждого теста — вызов assertEqual() для проверки ожидаемого результата; assertTrue() или assertFalse() для проверки условия; или assertRaises() для проверки того, что будет поднято конкретное исключение. Эти методы используются вместо оператора assert, чтобы запускатель тестов мог накапливать все результаты тестов и создавать отчёт.

Методы setUp() и tearDown() позволяют определять инструкции, которые будут выполняться перед и после каждого метода теста. Они рассматриваются более подробно в разделе Организация кода тестов.

Последний блок показывает простой способ запуска тестов. unittest.main() предоставляет интерфейс командной строки для скрипта тестов. При запуске из командной строки вышеприведенный скрипт выводит вывод, похожий на это:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Передача опции -v вашему скрипту тестов укажет unittest.main() на включение более подробного уровня отчёта и вывод следующего отчёта:

test_isupper (__main__.TestStringMethods.test_isupper) ... ok
test_split (__main__.TestStringMethods.test_split) ... ok
test_upper (__main__.TestStringMethods.test_upper) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

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

Изменено в версии 3.11: Поведение возвращения значения из метода теста (кроме значения по умолчанию None ) теперь устарело.

Интерфейс командной строки

Модуль unittest можно использовать в командной строке для запуска тестов из модулей, классов или даже отдельных тестовых методов:

python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

Вы можете передать список с любой комбинацией имён модулей и полных квалифицированных имён классов или методов.

Тестовые модули также можно указать по пути к файлу:

python -m unittest tests/test_something.py

Это позволяет использовать автодополнение имён файлов в оболочке для указания тестового модуля. Указанный файл должен быть импортируем в качестве модуля. Путь преобразуется в имя модуля путём удаления '.py' и преобразования разделителей путей в '.'. Если вы хотите выполнить тестовый файл, который нельзя импортировать как модуль, вы должны выполнить этот файл напрямую.

Вы можете запустить тесты с более подробной информацией (более высоким уровнем детализации), передав флаг -v:

python -m unittest -v test_module

При выполнении без аргументов запускается Обнаружение тестов:

python -m unittest

Для просмотра списка всех параметров командной строки:

python -m unittest -h

Изменено в версии 3.2: В более ранних версиях можно было запускать только отдельные тестовые методы, а не модули или классы.

Параметры командной строки

unittest поддерживает следующие параметры командной строки:

-b, --buffer

Стандартные потоки вывода и стандартные потоки ошибок буферизируются во время выполнения теста. Вывод во время прохождения теста игнорируется. Вывод отображается обычно при ошибке или сбое теста и добавляется к сообщениям об ошибках.

-c, --catch

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

Отображение локальных переменных в отслеживающих отладочных выводах.

--durations N

Отображение N самых медленных тестовых случаев (N=0 для всех).

Добавлена в версии 3.2: Параметры командной строки -b, -c и -f были добавлены.

Добавлена в версии 3.5: Параметр командной строки --locals.

Добавлена в версии 3.7: Параметр командной строки -k.

Добавлена в версии 3.12: Параметр командной строки --durations.

Командная строка также может использоваться для обнаружения тестов, для запуска всех тестов в проекте или только подмножества.

Обнаружение тестов

Добавлена в версии 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.

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

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

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

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

Изменено в версии 3.11: unittest удалил поддержку пакетов с пространством имён в Python 3.11. Она была сломана с Python 3.7. Каталоги, содержащие каталог начала и подкаталоги, содержащие тесты, должны быть обычными пакетами, которые имеют __init__.py файл.

Каталоги, содержащие каталог начала, всё ещё могут быть пакетами с пространством имён. В этом случае вам необходимо указать каталог начала как имён пакет, а целевой каталог явно. Например:

# proj/  <-- current directory
#   namespace/
#     mypkg/
#       __init__.py
#       test_mypkg.py

python -m unittest discover -s namespace.mypkg -t .

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

Основными строительными блоками модульного тестирования являются тестовые случаи — отдельные сценарии, которые должны быть настроены и проверены на корректность. В 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.test_format) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase.test_nothing) ... skipped 'demonstrating skipping'
test_maybe_skipped (__main__.MyTestCase.test_maybe_skipped) ... skipped 'external resource not available'
test_windows_support (__main__.MyTestCase.test_windows_support) ... skipped 'requires Windows'

----------------------------------------------------------------------
Ran 4 tests in 0.005s

OK (skipped=4)

Классы можно пропускать так же, как и методы:

@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
    def test_not_run(self):
        pass

TestCase.setUp() также может пропустить тест. Это полезно, когда ресурс, который нужно настроить, недоступен.

Ожидаемые ошибки используют декоратор expectedFailure().

class ExpectedFailureTestCase(unittest.TestCase):
    @unittest.expectedFailure
    def test_fail(self):
        self.assertEqual(1, 0, "broken")

Легко создать собственные декораторы пропуска, создав декоратор, который вызывает skip() для теста, когда нужно его пропустить. Этот декоратор пропускает тест, если у переданного объекта есть определенный атрибут:

def skipUnlessHasattr(obj, attr):
    if hasattr(obj, attr):
        return lambda func: func
    return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))

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

@unittest.skip(reason)

Безусловное пропускание декорируемого теста. 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.test_even) (i=1)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=3)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=5)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

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

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
END_OF_DOCUMENT_MARKER

Классы и функции

В этом разделе подробно описывается API unittest.

Тестовые случаи

class unittest.TestCase(methodName='runTest')

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

Каждый экземпляр TestCase выполнит один базовый метод: метод с именем methodName. В большинстве случаев использования TestCase, вы не будете изменять methodName или переопределять метод по умолчанию runTest().

Изменено в версии 3.2: TestCase может быть успешно создан без указания methodName. Это упрощает эксперименты с TestCase из интерактивного интерпретатора.

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

Методы первой группы (запуск теста) являются:

setUp()

Метод, вызываемый для подготовки тестового окружения. Он вызывается непосредственно перед вызовом тестового метода; любое исключение, кроме AssertionError или SkipTest, поднятое этим методом, будет рассматриваться как ошибка, а не как сбой теста. По умолчанию ничего не делает.

tearDown()

Метод, вызываемый сразу после вызова тестового метода и записи результата. Он вызывается даже если тестовый метод поднял исключение, поэтому реализация в производных классах может потребовать особой осторожности при проверке внутреннего состояния. Любое исключение, кроме AssertionError или SkipTest, поднятое этим методом, будет рассматриваться как дополнительная ошибка, а не как сбой теста (тем самым увеличивая общее количество сообщённых ошибок). Этот метод будет вызван только в случае успешного завершения setUp(), независимо от результата тестового метода. По умолчанию ничего не делает.

setUpClass()

Метод класса, вызываемый перед запуском тестов в отдельном классе. setUpClass вызывается с классом в качестве единственного аргумента и должен быть помечен как classmethod():

@classmethod
def setUpClass(cls):
    ...

См. Фикстуры класса и модуля для получения дополнительных сведений.

Добавлен в версии 3.2.

tearDownClass()

Метод класса, вызываемый после запуска тестов в отдельном классе. tearDownClass вызывается с классом в качестве единственного аргумента и должен быть помечен как classmethod():

@classmethod
def tearDownClass(cls):
    ...

См. Фикстуры класса и модуля для получения дополнительных сведений.

Добавлен в версии 3.2.

run(result=None)

Запустить тест, собрав результат в объект TestResult, переданный в качестве result. Если result пропущен или None, создаётся временный объект результата (вызовом метода defaultTestResult()) и используется. Объект результата возвращается вызывающей стороне метода run().

То же самое можно сделать, просто вызвав экземпляр TestCase.

Изменено в версии 3.3: Предыдущие версии run не возвращали результат. То же самое не происходило и при вызове экземпляра.

skipTest(reason)

Вызов этого во время тестового метода или setUp() пропускает текущий тест. См. Пропуск тестов и ожидаемые ошибки для получения дополнительной информации.

Добавлен в версии 3.1.

subTest(msg=None, **params)

Возвращает менеджер контекста, который выполняет заключённый блок кода в качестве подтеста. msg и params — необязательные произвольные значения, которые отображаются всякий раз, когда подтест терпит неудачу, позволяя чётко их идентифицировать.

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

См. Различение итераций тестов с помощью подтестов для получения дополнительной информации.

Добавлен в версии 3.4.

debug()

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

Класс TestCase предоставляет несколько методов assert для проверки и отчёта о сбоях. В следующей таблице перечислены наиболее часто используемые методы (см. таблицы ниже для получения более подробной информации о методах assert):

Метод

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

Новое в

assertEqual(a, b)

a == b

assertNotEqual(a, b)

a != b

assertTrue(x)

bool(x) is True

assertFalse(x)

bool(x) is False

assertIs(a, b)

a is b

3.1

assertIsNot(a, b)

a is not b

3.1

assertIsNone(x)

x is None

3.1

assertIsNotNone(x)

x is not None

3.1

assertIn(a, b)

a in b

3.1

assertNotIn(a, b)

a not in b

3.1

assertIsInstance(a, b)

isinstance(a, b)

3.2

assertNotIsInstance(a, b)

not isinstance(a, b)

3.2

Все методы assert принимают аргумент msg, который, если указан, используется в качестве сообщения об ошибке при сбое (см. также longMessage). Обратите внимание, что аргумент msg в ключевых словах может быть передан в assertRaises(), assertRaisesRegex(), assertWarns(), assertWarnsRegex() только в том случае, если они используются как менеджеры контекста.

assertEqual(first, second, msg=None)

Проверка, что first и second равны. Если значения не сравниваются как равные, тест завершится сбоем.

Кроме того, если first и second являются точно одного типа и одним из списком, кортежом, словарем, набором, неизменяемым набором или строкой, или любым типом, который подкласс регистрирует с помощью 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

Список строк, содержащих отформатированный вывод соответствующих сообщений.

Пример:

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

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

Если заданы оба delta и places, возникает TypeError.

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

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

Проверка, что первое значение соответственно >, >=, < или <= второго значения в зависимости от имени метода. В противном случае тест завершится ошибкой:

>>> 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().

assertCountEqual(first, second, msg=None)

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

Дубликаты элементов не игнорируются при сравнении первого и второго. Проверяется, имеет ли каждый элемент одинаковое количество в обеих последовательностях. Эквивалентно: assertEqual(Counter(list(first)), Counter(list(second))), но также работает с последовательностями неизменяемых объектов.

Добавлен в версии 3.2.

Метод assertEqual() передает проверку равенства для объектов одного типа различным методам, специфичным для типа. Эти методы уже реализованы для большинства встроенных типов, но также можно зарегистрировать новые методы с помощью addTypeEqualityFunc():

addTypeEqualityFunc(typeobj, function)

Регистрирует метод, специфичный для типа, вызываемый методом assertEqual(), для проверки, равны ли два объекта одного и того же типа (не подклассы). 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)

Проверка, что многострочная строка первая равна строке вторая. При несовпадении в сообщении об ошибке будет включена разница между двумя строками, выделяющая отличия. Этот метод используется по умолчанию при сравнении строк с помощью assertEqual().

Добавлен в версии 3.1.

assertSequenceEqual(first, second, msg=None, seq_type=None)

Проверка, что две последовательности равны. Если указан seq_type, то первая и вторая должны быть экземплярами seq_type, в противном случае будет выброшено исключение. Если последовательности отличаются, строится сообщение об ошибке, которое показывает разницу между ними.

Этот метод не вызывается напрямую методом assertEqual(), но используется для реализации assertListEqual() и assertTupleEqual().

Добавлен в версии 3.1.

assertListEqual(first, second, msg=None)
assertTupleEqual(first, second, msg=None)

Проверка, что два списка или кортежа равны. Если нет, строится сообщение об ошибке, которое показывает только различия между ними. Ошибка также возникает, если один из параметров имеет неправильный тип. Эти методы используются по умолчанию при сравнении списков или кортежей с помощью assertEqual().

Добавлен в версии 3.1.

assertSetEqual(first, second, msg=None)

Проверка, что два множества равны. Если нет, строится сообщение об ошибке, которое перечисляет различия между множествами. Этот метод используется по умолчанию при сравнении множеств или неизменяемых множеств с assertEqual().

Ошибка возникает, если у первого или второго нет метода set.difference().

Добавлен в версии 3.1.

assertDictEqual(first, second, msg=None)

Проверка, что два словаря равны. Если нет, строится сообщение об ошибке, которое показывает различия в словарях. Этот метод будет использоваться по умолчанию для сравнения словарей в вызовах assertEqual().

Добавлен в версии 3.1.

Наконец, TestCase предоставляет следующие методы и атрибуты:

fail(msg=None)

Безусловно сигнализирует об ошибке теста с msg или None в качестве сообщения об ошибке.

failureException

Этот атрибут класса задаёт исключение, генерируемое методом теста. Если тестовому фреймворку нужно использовать специализированное исключение, возможно, для переноса дополнительной информации, он должен быть подклассом этого исключения, чтобы «справедливо» работать со фреймворком. Исходное значение этого атрибута — AssertionError.

longMessage

Это атрибут класса, определяющий, что происходит, когда пользовательское сообщение об ошибке передается в качестве аргумента msg вызову assertXYY, который завершается ошибкой. True — значение по умолчанию. В этом случае пользовательское сообщение добавляется в конец стандартного сообщения об ошибке. При установке в значение False, пользовательское сообщение заменяет стандартное сообщение.

Настройка класса может быть переопределена в отдельных методах теста путём присвоения атрибуту экземпляра 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, если описание не было предоставлено. По умолчанию этот метод возвращает первую строку docstring метода теста, если она доступна, или None.

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

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

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

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

Добавлен в версии 3.1.

enterContext(cm)

Входит в предоставленный менеджер контекста. При успешном завершении, также добавляет его метод __exit__() как функцию очистки с помощью addCleanup() и возвращает результат метода __enter__().

Добавлен в версии 3.11.

doCleanups()

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

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

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

Добавлен в версии 3.1.

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

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

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

Добавлен в версии 3.8.

classmethod enterClassContext(cm)

Входит в предоставленный менеджер контекста. При успешном завершении, также добавляет его метод __exit__() как функцию очистки с помощью addClassCleanup() и возвращает результат метода __enter__().

Добавлен в версии 3.11.

classmethod doClassCleanups()

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

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

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

Добавлен в версии 3.8.

class unittest.IsolatedAsyncioTestCase(methodName='runTest')

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

Добавлен в версии 3.8.

loop_factory

loop_factory, переданный в asyncio.Runner. Переопределите в подклассах с помощью asyncio.EventLoop, чтобы избежать использования системы политик asyncio.

Добавлен в версии 3.13.

coroutine asyncSetUp()

Метод, вызываемый для подготовки тестового фикстура. Вызывается после setUp(). Вызывается непосредственно перед вызовом тестового метода; любое исключение, кроме AssertionError или SkipTest, которое возникает в этом методе, будет считаться ошибкой, а не сбоем теста. По умолчанию ничего не делает.

coroutine asyncTearDown()

Метод, вызываемый сразу после того, как был вызван тестовый метод и результат записан. Вызывается перед tearDown(). Вызывается даже если тестовый метод вызвал исключение, поэтому реализации в подклассах нужно быть особенно внимательными к проверке внутреннего состояния. Любое исключение, отличное от AssertionError или SkipTest, которое возникает в этом методе, будет считаться дополнительной ошибкой, а не сбоем теста (тем самым увеличивая общее количество сообщенных ошибок). Этот метод будет вызван только в случае успешного выполнения asyncSetUp(), независимо от результата выполнения тестового метода. По умолчанию ничего не делает.

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

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

coroutine enterAsyncContext(cm)

Входит в предоставленный асинхронный контекстный менеджер. При успехе также добавляет его метод __aexit__() как функцию очистки с помощью addAsyncCleanup() и возвращает результат метода __aenter__().

Добавлен в версии 3.11.

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.

Группировка тестов

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)

Возвращает набор всех тестовых случаев, содержащихся в 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: Добавлен ключевой аргумент pattern.

Изменено в версии 3.12: Удалён недокументированный и неофициальный параметр use_load_tests.

loadTestsFromName(name, module=None)

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

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

Например, если у вас есть модуль SampleTests с классом SampleTestCase (производным от TestCase), содержащим три тестовых метода (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).

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

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

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

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

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

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

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

Добавлена в версии 3.2.

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

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

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

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

Изменено в версии 3.11: start_dir не может быть пакетом-пространством имён. Это было сломано с Python 3.7 и Python 3.11 официально удалили его.

Изменено в версии 3.13: top_level_dir хранится только на время вызова discover.

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

testMethodPrefix

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

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

sortTestMethodsUsing

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

suiteClass

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

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

testNamePatterns

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

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

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

Добавлена в версии 3.7.

class unittest.TestResult

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

Объект TestResult хранит результаты набора тестов. Классы TestCase и TestSuite гарантируют, что результаты записываются должным образом; авторы тестов не должны беспокоиться о записи результатов тестов.

Фреймворки тестирования, построенные на основе unittest, могут потребовать доступ к объекту TestResult, сгенерированному при запуске набора тестов для целей отчётности; экземпляр TestResult возвращается методом TestRunner.run() для этой цели.

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

errors

Список, содержащий 2-кортежи из экземпляров TestCase и строк, содержащих отформатированные трассировки стека. Каждый кортеж представляет собой тест, который вызвал непредвиденное исключение.

failures

Список, содержащий 2-кортежи из экземпляров TestCase и строк, содержащих отформатированные трассировки стека. Каждый кортеж представляет собой тест, в котором сбой был явно сигнализирован с помощью методов assert* methods.

skipped

Список, содержащий 2-кортежи из экземпляров TestCase и строк, содержащих причину пропуска теста.

Добавлен в версии 3.1.

expectedFailures

Список, содержащий 2-кортежи из экземпляров TestCase и строк, содержащих отформатированные трассировки стека. Каждый кортеж представляет собой ожидаемый сбой или ошибку тестового случая.

unexpectedSuccesses

Список, содержащий экземпляры TestCase, которые были помечены как ожидаемые сбои, но прошли успешно.

collectedDurations

Список, содержащий 2-кортежи имён тестовых случаев и чисел с плавающей точкой, представляющих время выполнения каждого запущенного теста.

Добавлен в версии 3.12.

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.

addDuration(test, elapsed)

Вызывается по завершении тестового случая. elapsed — время в секундах, включающее выполнение завершающих функций.

Добавлена в версии 3.12.

class unittest.TextTestResult(stream, descriptions, verbosity, *, durations=None)

Конкретная реализация TestResult, используемая TextTestRunner. Подклассы должны принимать **kwargs для обеспечения совместимости при изменениях интерфейса.

Добавлена в версии 3.2.

Изменено в версии 3.12: Добавлен параметр durations.

unittest.defaultTestLoader

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

class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False, durations=None)

Реализация базового тестового исполнителя, выводищая результаты в поток. Если stream — None, по умолчанию используется sys.stderr в качестве потока вывода. Этот класс имеет несколько настраиваемых параметров, но в целом очень прост. Графические приложения, которые запускают наборы тестов, должны предоставлять альтернативные реализации. Такие реализации должны принимать **kwargs при изменении интерфейса построения исполнителей при добавлении функций в unittest.

По умолчанию этот исполнитель показывает DeprecationWarning, PendingDeprecationWarning, ResourceWarning и ImportWarning, даже если они по умолчанию игнорируются. Это поведение можно переопределить с помощью параметров Python -Wd или -Wa (см. Управление предупреждениями), оставив warnings в значении None.

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

Изменено в версии 3.2: По умолчанию поток устанавливается в sys.stderr во время инициализации, а не во время импорта.

Изменено в версии 3.5: Добавлен параметр tb_locals.

Изменено в версии 3.12: Добавлен параметр durations.

_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)

Программа командной строки, загружающая набор тестов из модуля и выполняющая их; это в первую очередь предназначено для удобного запуска модулей тестов. Самое простое использование этой функции — включить следующую строку в конце скрипта теста:

if __name__ == '__main__':
    unittest.main()

Вы можете запустить тесты с более подробной информацией, передав аргумент verbosity:

if __name__ == '__main__':
    unittest.main(verbosity=2)

Аргумент defaultTest — это имя одного теста или итерируемый объект имён тестов для запуска, если имена тестов не указаны через argv. Если он не указан или None и имена тестов не предоставлены через argv, выполняются все тесты, найденные в модуле.

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

Аргумент testRunner может быть классом исполнителя тестов или уже созданным экземпляром. По умолчанию main вызывает sys.exit() с кодом выхода, указывающим на успех (0) или неудачу (1) проведённых тестов. Код выхода 5 указывает, что тесты не запускались или были пропущены.

Аргумент 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 возвращает объект с атрибутом result, содержащим результат выполненных тестов в виде unittest.TestResult.

Изменено в версии 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.

classmethod unittest.enterModuleContext(cm)

Перейти к предоставленному менеджеру контекста. При успешном выполнении также добавьте его метод __exit__() как функцию очистки с помощью addModuleCleanup() и верните результат метода __enter__().

Добавлен в версии 3.11.

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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/unittest.html

Spec-Zone.ru

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