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, включая фреймворки функционального тестирования и библиотеки имитационных объектов.

Список рассылки Testing in 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

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

Функции, обеспечивающие эту возможность, описаны в разделе Обработка сигналов.

-f, --failfast

Остановить выполнение тестов при первой ошибке или сбое.

-k

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

Шаблоны, содержащие символ подстановки (*), сопоставляются с именем теста с помощью fnmatch.fnmatchcase(); в противном случае используется простое сопоставление подстрок с учётом регистра.

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

Например, -k foo соответствует foo_tests.SomeTest.test_something, bar_tests.SomeTest.test_foo, но не bar_tests.FooTest.test_something.

--locals

Показывать локальные переменные в трассировках стека.

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

Изменено в версии 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 предоставляет для этого механизм — набор тестов, представленный классом TestSuite из unittest. В большинстве случаев вызов unittest.main() выполнит нужные действия: соберёт все тестовые примеры модуля и запустит их.

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

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

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

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

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

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

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

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

Для следующей тестовой функции:

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

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

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

Примечание

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

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

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

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

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

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

Простейший вариант пропуска выглядит так:

class MyTestCase(unittest.TestCase):

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

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # 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

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

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

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

class unittest.TestCase(methodName='runTest')

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

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

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

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

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

setUp()

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

tearDown()

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

setUpClass()

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

@classmethod
def setUpClass(cls):
    ...

Подробнее см. в разделе Тестовое окружение класса и модуля.

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

tearDownClass()

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

@classmethod
def tearDownClass(cls):
    ...

Подробнее см. в разделе Тестовое окружение класса и модуля.

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

run(result=None)

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

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

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

skipTest(reason)

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

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

subTest(msg=None, **params)

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

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

Подробнее см. в разделе Различение итераций теста с помощью под-тестов.

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

debug()

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

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

Метод

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

Добавлен в

assertEqual(a, b)

a == b

assertNotEqual(a, b)

a != b

assertTrue(x)

bool(x) is True

assertFalse(x)

bool(x) is False

assertIs(a, b)

a is b

3.1

assertIsNot(a, b)

a is not b

3.1

assertIsNone(x)

x is None

3.1

assertIsNotNone(x)

x is not None

3.1

assertIn(a, b)

a in b

3.1

assertNotIn(a, b)

a not in b

3.1

assertIsInstance(a, b)

isinstance(a, b)

3.2

assertNotIsInstance(a, b)

not isinstance(a, b)

3.2

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

assertEqual(first, second, msg=None)

Проверяет, равны ли first и second. Если значения не равны, тест завершается неудачно.

Кроме того, если first и second имеют в точности одинаковый тип, который является одним из типов list, tuple, dict, set, frozenset или str, либо типом, для которого подкласс зарегистрировал функцию с помощью addTypeEqualityFunc(), вызывается функция проверки равенства для конкретного типа, чтобы сформировать более полезное сообщение об ошибке по умолчанию (см. также список методов для конкретных типов).

Изменено в версии 3.1: Добавлен автоматический вызов функции проверки равенства для конкретного типа.

Изменено в версии 3.2: assertMultiLineEqual() добавлен в качестве функции проверки равенства по умолчанию для сравнения строк.

assertNotEqual(first, second, msg=None)

Проверяет, что first и second не равны. Если значения равны, тест завершается неудачно.

assertTrue(expr, msg=None)
assertFalse(expr, msg=None)

Проверяет, что expr истинно (или ложно).

Обратите внимание, что это эквивалентно bool(expr) is True, а не expr is True (для последнего используйте assertIs(expr, True)). Также следует избегать этого метода, если доступны более специализированные методы (например, assertEqual(a, b) вместо assertTrue(a == b)), поскольку в случае провала они предоставляют более информативное сообщение об ошибке.

assertIs(first, second, msg=None)
assertIsNot(first, second, msg=None)

Проверяет, являются ли first и second одним и тем же объектом (или не являются).

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

assertIsNone(expr, msg=None)
assertIsNotNone(expr, msg=None)

Проверяет, является ли expr значением None (или не является).

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

assertIn(member, container, msg=None)
assertNotIn(member, container, msg=None)

Проверяет, входит ли member в container (или не входит).

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

assertIsInstance(obj, cls, msg=None)
assertNotIsInstance(obj, cls, msg=None)

Проверяет, является ли obj экземпляром cls (или не является). 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 или объектом str, содержащим имя регистратора. По умолчанию используется корневой регистратор, который перехватывает все сообщения, не заблокированные дочерними регистраторами с отключённой передачей сообщений родительскому регистратору.

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

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

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

records

Список объектов logging.LogRecord, соответствующих сообщениям журнала.

output

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

Пример:

with self.assertLogs('foo', level='INFO') as cm:
    logging.getLogger('foo').info('first message')
    logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
                             'ERROR:foo.bar:second message'])

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

assertNoLogs(logger=None, level=None)

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

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

Если указан, 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().

assertCountEqual(first, second, msg=None)

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

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

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

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

addTypeEqualityFunc(typeobj, function)

Регистрирует метод для конкретного типа, вызываемый методом assertEqual() для проверки равенства двух объектов с точно одинаковым типом typeobj (не подклассов). function должен принимать два позиционных аргумента и третий именованный аргумент msg=None, как и assertEqual(). При обнаружении неравенства первых двух параметров он должен вызывать исключение self.failureException(msg), по возможности предоставляя полезную информацию и подробно объясняя различия в сообщении об ошибке.

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

Список методов для конкретных типов, автоматически используемых методом assertEqual(), приведён в следующей таблице. Обычно нет необходимости вызывать эти методы напрямую.

Метод

Используется для сравнения

Добавлен в

assertMultiLineEqual(a, b)

строк

3.1

assertSequenceEqual(a, b)

последовательностей

3.1

assertListEqual(a, b)

списков

3.1

assertTupleEqual(a, b)

кортежей

3.1

assertSetEqual(a, b)

множеств или неизменяемых множеств

3.1

assertDictEqual(a, b)

словарей

3.1

assertMultiLineEqual(first, second, msg=None)

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

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

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

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

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

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

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

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

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

assertSetEqual(first, second, msg=None)

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

Проверка завершается неудачей, если у first или second отсутствует метод set.difference().

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

assertDictEqual(first, second, msg=None)

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

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

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

fail(msg=None)

Безусловно сообщает о неудаче теста, используя msg или None в качестве сообщения об ошибке.

failureException

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

longMessage

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

Настройку класса можно переопределить для отдельных методов теста, присвоив атрибуту экземпляра self.longMessage значение True или False перед вызовом методов assert.

Настройка класса сбрасывается перед каждым вызовом теста.

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

maxDiff

Этот атрибут задаёт максимальную длину различий, выводимых методами assert при неудачной проверке. По умолчанию она составляет 80*8 символов. Атрибут влияет на следующие методы 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, поэтому в Python 3.2 добавление имени теста перенесли в TextTestResult.

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.

async asyncSetUp()

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

async asyncTearDown()

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

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

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

async 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, содержащий производный от TestCase класс SampleTestCase с тремя тестовыми методами (test_one(), test_two() и test_three()), спецификатор 'SampleTests.SampleTestCase' заставит этот метод вернуть набор, запускающий все три тестовых метода. Спецификатор 'SampleTests.SampleTestCase.test_two' заставит его вернуть набор тестов, запускающий только тестовый метод test_two(). Спецификатор может ссылаться на модули и пакеты, которые ещё не импортированы; они будут импортированы в качестве побочного эффекта.

Метод может разрешать name относительно указанного module.

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

loadTestsFromNames(names, module=None)

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

getTestCaseNames(testCaseClass)

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

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

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

Все модули с тестами должны импортироваться из верхнего уровня проекта. Если начальный каталог не является каталогом верхнего уровня, необходимо отдельно указать 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, созданному при запуске набора тестов, для формирования отчётов; для этого метод TestRunner.run() возвращает экземпляр TestResult.

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

errors

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

failures

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

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, если среди тестов, помеченных декоратором expectedFailure(), есть случаи unexpectedSuccesses.

stop()

Этот метод можно вызвать, чтобы сообщить о необходимости прервать выполняемый набор тестов, установив для атрибута shouldStop значение True. Объекты TestRunner должны учитывать этот флаг и возвращаться, не запуская дополнительных тестов.

Например, класс TextTestRunner использует эту возможность, чтобы остановить тестовую платформу, когда пользователь прерывает работу с клавиатуры. Интерактивные инструменты, предоставляющие реализации TestRunner, могут использовать её аналогичным образом.

Следующие методы класса TestResult используются для поддержки внутренних структур данных. Их можно переопределять в подклассах, чтобы удовлетворить дополнительные требования к отчётности. Это особенно полезно при создании инструментов, обеспечивающих интерактивную отчётность во время выполнения тестов.

startTest(test)

Вызывается непосредственно перед запуском тестового случая test.

stopTest(test)

Вызывается после выполнения тестового случая test, независимо от результата.

startTestRun()

Вызывается один раз перед выполнением любых тестов.

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

stopTestRun()

Вызывается один раз после выполнения всех тестов.

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

addError(test, err)

Вызывается, когда тестовый случай test возбуждает неожиданное исключение. err — это кортеж в формате, возвращаемом sys.exc_info(): (type, value, traceback).

Реализация по умолчанию добавляет кортеж (test, formatted_err) к атрибуту экземпляра errors, где formatted_err — отформатированная трассировка стека, полученная из err.

addFailure(test, err)

Вызывается, когда тестовый случай test сообщает о неудаче. err — это кортеж в формате, возвращаемом sys.exc_info(): (type, value, traceback).

Реализация по умолчанию добавляет кортеж (test, formatted_err) к атрибуту экземпляра failures, где formatted_err — отформатированная трассировка стека, полученная из err.

addSuccess(test)

Вызывается, когда тестовый случай test завершается успешно.

Реализация по умолчанию ничего не делает.

addSkip(test, reason)

Вызывается, когда тестовый случай test пропускается. reason — причина, указанная тестом для пропуска.

Реализация по умолчанию добавляет кортеж (test, reason) к атрибуту экземпляра skipped.

addExpectedFailure(test, err)

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

Реализация по умолчанию добавляет кортеж (test, formatted_err) к атрибуту экземпляра expectedFailures, где formatted_err — отформатированная трассировка стека, полученная из err.

addUnexpectedSuccess(test)

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

Реализация по умолчанию добавляет тест к атрибуту экземпляра unexpectedSuccesses.

addSubTest(test, subtest, outcome)

Вызывается по завершении подтеста. test — это тестовый случай, соответствующий тестовому методу. subtest — это пользовательский экземпляр TestCase, описывающий подтест.

Если outcome равен None, подтест завершился успешно. В противном случае он завершился неудачей с исключением, а outcome — это кортеж в формате, возвращаемом sys.exc_info(): (type, value, traceback).

Реализация по умолчанию ничего не делает, если подтест завершился успешно, а неудачи подтестов записывает как обычные неудачи.

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

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. Если resultclass не указан, по умолчанию используется TextTestResult. Класс результата создаётся со следующими аргументами:

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() с кодом завершения, указывающим на успех (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, если программе python передан параметр -W (см. раздел Управление предупреждениями); в противном случае ему присваивается значение '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() для очистки ресурсов, использованных во время тестирования класса. Функции вызываются в порядке, обратном порядку их добавления (последним добавлен — первым выполнен). При вызове им передаются позиционные и именованные аргументы, указанные при добавлении в addModuleCleanup().

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

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

unittest.enterModuleContext(cm)

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

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

unittest.doModuleCleanups()

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

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

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

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

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

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

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

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

Spec-Zone.ru

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