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

Источник: Lib/unittest/__init__.py


(Если вы уже знакомы с основными понятиями тестирования, вам лучше перейти к the list of assert methods).

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

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

испытательное приспособление

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

тестовый пример

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

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

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

испытатель

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

См.также

Модуль doctest

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

Simple Smalltalk Testing: With Patterns

Оригинальная статья Кента Бека о тестировании фреймворков с использованием паттерна, разделяемого unittest.

pytest

Сторонний фреймворк unittest с облегченным синтаксисом для написания тестов. Например, assert func(10) == 42.

The Python Testing Tools Taxonomy

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

Testing in Python Mailing List

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

Скрипт Tools/unittestgui/unittestgui.py в исходном дистрибутиве Python представляет собой GUI-инструмент для обнаружения и выполнения тестов. Он предназначен в основном для простоты использования теми, кто только начинает заниматься модульным тестированием. Для производственных сред рекомендуется, чтобы тесты выполнялись с помощью системы непрерывной интеграции, например 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.

Функции, обеспечивающие эту функциональность, см. в разделе Signal Handling.

-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 для всех).

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

Added in version 3.5: Опция командной строки --locals.

Added in version 3.7: Опция командной строки -k.

Added in version 3.12: Опция командной строки --durations.

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

Тестовое открытие

Added in version 3.2.

Unittest поддерживает простое обнаружение тестов. Для совместимости с обнаружением тестов все тестовые файлы должны быть modules или packages, импортируемые из каталога верхнего уровня проекта (это означает, что их имена файлов должны быть правильными identifiers).

Обнаружение тестов реализовано в 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. Имя пакета, которое вы передадите, будет импортировано, и его местоположение в файловой системе будет использовано в качестве начального каталога.

Осторожно

Test discovery загружает тесты, импортируя их. После того как test discovery найдет все файлы тестов из указанного вами начального каталога, он преобразует пути в имена пакетов для импорта. Например, foo/bar/baz.py будет импортирован как foo.bar.baz.

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

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

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

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

Изменено в версии 3.11: unittest отказался от поддержки namespace packages в 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 .

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

Основными строительными блоками модульного тестирования являются test cases — отдельные сценарии, которые должны быть созданы и проверены на корректность. В 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* methods, предоставляемых базовым классом TestCase. Если тест завершится неудачей, будет поднято исключение с поясняющим сообщением, а unittest определит тестовый случай как failure. Любые другие исключения будут рассматриваться как errors.

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

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

Рекомендуется использовать реализации TestCase для группировки тестов в соответствии с проверяемыми ими функциями. unittest предоставляет механизм для этого: test suite, представленный классом unittest 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-базированных тестов.

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

Added in version 3.1.

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

Пропустить тест - это просто использовать skip() decorator или одного из его условных вариантов, вызова 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

Это результат выполнения приведенного выше примера в режиме verbose:

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)

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

@unittest.skipIf(condition, reason)

Пропустите украшенный тест, если условие истинно.

@unittest.skipUnless(condition, reason)

Пропустите украшенный тест, если условие не истинно.

@unittest.expectedFailure

Пометьте тест как ожидаемый провал или ошибку. Если тест завершился неудачей или ошибкой в самой тестовой функции (а не в одном из методов test fixture), то он будет считаться успешным. Если тест пройдет, он будет считаться провальным.

exception unittest.SkipTest(reason)

Это исключение возникает, чтобы пропустить тест.

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

Пропущенные тесты не будут иметь setUp() или tearDown() вокруг них. В пропущенных классах не будет выполняться setUpClass() или tearDownClass(). В пропущенных модулях не будет выполняться setUpModule() или tearDownModule().

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

Added in version 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):
    ...

Более подробную информацию см. в разделе Class and Module Fixtures.

Added in version 3.2.

tearDownClass()

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

@classmethod
def tearDownClass(cls):
    ...

Более подробную информацию см. в разделе Class and Module Fixtures.

Added in version 3.2.

run(result=None)

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

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

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

skipTest(reason)

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

Added in version 3.1.

subTest(msg=None, **params)

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

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

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

Added in version 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(), будет вызвана функция равенства, специфичная для типа, чтобы сгенерировать более полезное сообщение об ошибке по умолчанию (см. также list of type-specific methods).

Изменено в версии 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 являются (или не являются) одним и тем же объектом.

Added in version 3.1.

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

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

Added in version 3.1.

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

Проверьте, что член находится (или не находится) в контейнере.

Added in version 3.1.

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

Проверьте, что obj является (или не является) экземпляром cls (который может быть классом или кортежем классов, как поддерживается isinstance()). Чтобы проверить точный тип, используйте assertIs(type(obj), cls).

Added in version 3.2.

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

Метод

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

Новое в

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

fun(*args, **kwds) повышает exc

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

fun(*args, **kwds) вызывает exc, а сообщение соответствует regex r.

3.1

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

fun(*args, **kwds) повышает warn

3.2

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

fun(*args, **kwds) вызывает предупреждение warn и сообщение соответствует regex r.

3.2

assertLogs(logger, level)

Блок with ведет журнал на logger с минимальным уровнем.

3.4

assertNoLogs(logger, level)

Блок with не входит в систему

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

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

Added in version 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)

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

Added in version 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')

Added in version 3.2.

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

assertLogs(logger=None, level=None)

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

Если задано, 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'])

Added in version 3.4.

assertNoLogs(logger=None, level=None)

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

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

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

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

Added in version 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.

При указании дельты и места возникает сообщение 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"

Added in version 3.1.

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

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

Added in version 3.1: Добавлена под именем assertRegexpMatches.

Изменено в версии 3.2: Метод assertRegexpMatches() был переименован в assertRegex().

Added in version 3.2: assertNotRegex().

assertCountEqual(first, second, msg=None)

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

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

Added in version 3.2.

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

addTypeEqualityFunc(typeobj, function)

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

Added in version 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)

dicts

3.1

assertMultiLineEqual(first, second, msg=None)

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

Added in version 3.1.

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

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

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

Added in version 3.1.

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

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

Added in version 3.1.

assertSetEqual(first, second, msg=None)

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

Не работает, если ни у first, ни у second нет метода set.difference().

Added in version 3.1.

assertDictEqual(first, second, msg=None)

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

Added in version 3.1.

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

fail(msg=None)

Сигнализирует о неудаче теста безусловно, с сообщением об ошибке msg или None.

failureException

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

longMessage

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

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

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

Added in version 3.1.

maxDiff

Этот атрибут контролирует максимальную длину диффов, выводимых методами assert, которые сообщают о диффах при сбое. По умолчанию он равен 80*8 символов. Этот атрибут влияет на методы assert: assertSequenceEqual() (включая все делегированные ему методы сравнения последовательностей), assertDictEqual() и assertMultiLineEqual().

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

Added in version 3.2.

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

countTestCases()

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

defaultTestResult()

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

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

id()

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

shortDescription()

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

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

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

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

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

Added in version 3.1.

enterContext(cm)

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

Added in version 3.11.

doCleanups()

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

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

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

Added in version 3.1.

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

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

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

Added in version 3.8.

classmethod enterClassContext(cm)

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

Added in version 3.11.

classmethod doClassCleanups()

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

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

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

Added in version 3.8.

class unittest.IsolatedAsyncioTestCase(methodName='runTest')

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

Added in version 3.8.

loop_factory

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

Added in version 3.13.

coroutine asyncSetUp()

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

coroutine asyncTearDown()

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

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

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

coroutine enterAsyncContext(cm)

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

Added in version 3.11.

run(result=None)

Устанавливает новый цикл событий для выполнения теста, собирая результат в объект TestResult, переданный в качестве result. Если result опущен или None, создается временный объект result (путем вызова метода 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 в этот набор тестов.

Это эквивалентно итерации по тестам, вызывая 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

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

Added in version 3.5.

Объекты TestLoader имеют следующие методы:

loadTestsFromTestCase(testCaseClass)

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

Экземпляр тестового случая создается для каждого метода, названного getTestCaseNames(). По умолчанию это имена методов, начинающиеся с test. Если getTestCaseNames() не возвращает ни одного метода, но реализован метод runTest(), то вместо него создается один тестовый пример.

loadTestsFromModule(module, *, pattern=None)

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

Примечание

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

Если модуль предоставляет функцию load_tests, то она будет вызвана для загрузки тестов. Это позволяет модулям настраивать загрузку тестов. Это функция load_tests protocol. Аргумент шаблон передается в качестве третьего аргумента в 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, содержащий их. Будут загружены только те тестовые файлы, которые соответствуют шаблону. (Используется сопоставление шаблонов в стиле оболочки). Будут загружены только имена модулей, которые можно импортировать (т.е. являются действительными идентификаторами Python).

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

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

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

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

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

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

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

Added in version 3.2.

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

Изменено в версии 3.4: start_dir может быть namespace packages.

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

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

Изменено в версии 3.11: start_dir не может быть значением namespace packages. Эта функция не работает со времен 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*.

Added in version 3.7.

class unittest.TestResult

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

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

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

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

errors

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

failures

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

skipped

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

Added in version 3.1.

expectedFailures

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

unexpectedSuccesses

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

collectedDurations

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

Added in version 3.12.

shouldStop

Установите значение True, когда выполнение тестов должно быть остановлено на stop().

testsRun

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

buffer

Если установлено значение true, sys.stdout и sys.stderr будут буферизироваться между вызовами startTest() и stopTest(). Собранный вывод будет передан на настоящие sys.stdout и sys.stderr только в случае неудачи или ошибки теста. Любой вывод также прикрепляется к сообщению о неудаче/ошибке.

Added in version 3.2.

failfast

При значении true stop() будет вызываться при первом сбое или ошибке, останавливая выполнение теста.

Added in version 3.2.

tb_locals

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

Added in version 3.5.

wasSuccessful()

Возвращает True, если все запущенные на данный момент тесты пройдены, в противном случае возвращает False.

Изменено в версии 3.4: Возвращает False, если в тестах, помеченных декоратором expectedFailure(), были обнаружены unexpectedSuccesses.

stop()

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

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

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

startTest(test)

Вызывается, когда тестовый пример test собирается быть запущенным.

stopTest(test)

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

startTestRun()

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

Added in version 3.1.

stopTestRun()

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

Added in version 3.1.

addError(test, err)

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

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

addFailure(test, err)

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

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

addSuccess(test)

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

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

addSkip(test, reason)

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

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

addExpectedFailure(test, err)

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

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

addUnexpectedSuccess(test)

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

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

addSubTest(test, subtest, outcome)

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

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

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

Added in version 3.4.

addDuration(test, elapsed)

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

Added in version 3.12.

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

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

Added in version 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, даже если они равны ignored by default. Это поведение можно отменить, используя опции Python -Wd или -Wa (см. Warning control) и оставив 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. Класс result инстанцируется со следующими аргументами:

stream, descriptions, verbosity
run(test)

Этот метод является основным публичным интерфейсом для TextTestRunner. Этот метод принимает экземпляр TestSuite или TestCase. Вызовом _makeResult() создается TestResult, выполняется тест(ы) и результаты выводятся в 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)

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

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 имеют тот же эффект, что и одноименные command-line options.

Аргумент warnings задает warning filter, который должен использоваться при выполнении тестов. Если он не указан, то останется None, если в python передана опция -W (см. Warning control), в противном случае будет установлено значение 'default'.

Вызов main фактически возвращает экземпляр класса TestProgram. В нем хранится результат выполнения тестов в виде атрибута result.

Изменено в версии 3.1: Был добавлен параметр exit.

Изменено в версии 3.2: Добавлены параметры verbosity, failfast, catchbreak, buffer и warnings.

Изменено в версии 3.4: Параметр defaultTest был изменен, чтобы также принимать итерабельность имен тестов.

load_tests Протокол

Added in version 3.2.

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

Если тестовый модуль определяет load_tests, он будет вызван TestLoader.loadTestsFromModule() со следующими аргументами:

load_tests(loader, standard_tests, 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

Если discovery запускается в каталоге, содержащем пакет, либо из командной строки, либо с помощью вызова TestLoader.discover(), то пакет __init__.py будет проверен на наличие load_tests. Если такой функции не существует, discovery выполнит поиск в пакете, как если бы это был просто другой каталог. В противном случае обнаружение тестов пакета будет оставлено на усмотрение 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: Discovery больше не проверяет имена пакетов на совпадение с шаблоном из-за невозможности совпадения имен пакетов с шаблоном по умолчанию.

Крепления для классов и модулей

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

Added in version 3.8.

classmethod unittest.enterModuleContext(cm)

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

Added in version 3.11.

unittest.doModuleCleanups()

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

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

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

Added in version 3.8.

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

Added in version 3.2.

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

Обработчик сигналов control-c пытается сохранить совместимость с кодом или тестами, которые устанавливают свой собственный обработчик signal.SIGINT. Если вызывается обработчик unittest, но не установленный обработчик signal.SIGINT, т. е. он был заменен тестируемой системой и делегирован ей, то вызывается обработчик по умолчанию. Обычно это будет ожидаемым поведением кода, который заменяет установленный обработчик и делегирует ему полномочия. Для отдельных тестов, которым требуется отключить обработку unittest control-c, можно использовать декоратор removeHandler().

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

unittest.installHandler()

Установите обработчик control-c. При получении signal.SIGINT (обычно в ответ на нажатие пользователем кнопки control-c) у всех зарегистрированных результатов вызывается stop().

unittest.registerResult(result)

Зарегистрируйте объект TestResult для обработки контрола. Регистрация результата хранит слабую ссылку на него, поэтому не предотвращает сборку мусора.

Регистрация объекта TestResult не имеет побочных эффектов, если обработка control-c не включена, поэтому тестовые среды могут безоговорочно регистрировать все создаваемые ими результаты независимо от того, включена обработка или нет.

unittest.removeResult(result)

Удаление зарегистрированного результата. Если результат был удален, то stop() больше не будет вызываться для этого объекта результата в ответ на control-c.

unittest.removeHandler(function=None)

При вызове без аргументов эта функция удаляет обработчик control-c, если он был установлен. Эта функция также может быть использована в качестве декоратора тестов для временного удаления обработчика на время выполнения теста:

@unittest.removeHandler
def test_signal_handling(self):
    ...