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 framework с облегченным синтаксисом для написания тестов. Например, assert func(10) == 42.

The Python Testing Tools Taxonomy

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

Testing in Python Mailing List

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

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

Основной пример

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

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

import unittest

class TestStringMethods(unittest.TestCase):

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

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

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

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

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

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

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

В последнем блоке показан простой способ запуска тестов. unittest.main() предоставляет интерфейс командной строки к тестовому сценарию. При запуске из командной строки вышеприведенный сценарий выдает результат, который выглядит следующим образом:

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

OK

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

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

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

OK

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

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

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

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

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

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

python -m unittest tests/test_something.py

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

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

python -m unittest -v test_module

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

python -m unittest

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

python -m unittest -h

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

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

unittest поддерживает эти параметры командной строки:

-b, --buffer

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

-c, --catch

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

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

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

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

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

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

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

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

Unittest поддерживает простое обнаружение тестов. Для совместимости с обнаружением тестов все тестовые файлы должны быть modules или packages (включая namespace 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).

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

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

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

Добавлено в версии 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) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available'
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'

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

OK (skipped=4)

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

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

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

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

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

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

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

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

@unittest.skip(reason)

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

@unittest.skipIf(condition, reason)

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

@unittest.skipUnless(condition, reason)

Пропустите тест decorated, если условие не истинно.

@unittest.expectedFailure

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

exception unittest.SkipTest(reason)

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

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

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

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

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

Когда между вашими тестами есть очень небольшие различия, например, некоторые параметры, unittest позволяет различать их внутри тела метода теста с помощью менеджера контекста subTest().

Например, следующий тест:

class NumbersTest(unittest.TestCase):

    def test_even(self):
        """
        Test that numbers between 0 and 5 are all even.
        """
        for i in range(0, 6):
            with self.subTest(i=i):
                self.assertEqual(i % 2, 0)

приведет к следующему результату:

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

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

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

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

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

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

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

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

class unittest.TestCase(methodName='runTest')

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

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

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

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

Методы в первой группе (выполнение теста) следующие:

setUp()

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

tearDown()

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

setUpClass()

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

@classmethod
def setUpClass(cls):
    ...

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

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

tearDownClass()

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

@classmethod
def tearDownClass(cls):
    ...

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

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

run(result=None)

Выполните тест, собирая результат в объект TestResult, переданный в качестве result. Если result опущен или None, создается временный объект result (путем вызова метода 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 являются одинаковыми типами и одним из list, tuple, dict, set, frozenset или str или любым типом, который подкласс регистрирует с помощью addTypeEqualityFunc(), будет вызвана специфическая для типа функция равенства, чтобы сгенерировать более полезное сообщение об ошибке по умолчанию (см. также list of type-specific methods).

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

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

assertNotEqual(first, second, msg=None)

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

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)

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

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

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

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

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

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

Метод

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

Новое в

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

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

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

fun(*args, **kwds) вызывает exc и сообщение соответствует 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, верните менеджер контекста, чтобы тестируемый код можно было написать inline, а не как функцию:

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, верните менеджер контекста, чтобы тестируемый код можно было написать inline, а не как функцию:

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 или в одном из его дочерних элементов зарегистрировано хотя бы одно сообщение с заданным уровнем.

Если задано, 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 или одном из его дочерних элементов не зарегистрировано никаких сообщений, по крайней мере, с заданным уровнем.

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

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

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

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

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

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

Добавлено в версии 3.2: assertNotRegex().

Добавлено в версии 3.5: Имя assertNotRegexpMatches является устаревшим псевдонимом для assertNotRegex().

assertCountEqual(first, second, msg=None)

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

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

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

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

addTypeEqualityFunc(typeobj, function)

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

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

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

Метод

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

Новое в

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

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

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

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

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

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

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

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

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

assertSetEqual(first, second, msg=None)

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

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

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

assertDictEqual(first, second, msg=None)

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

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

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

fail(msg=None)

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

failureException

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

longMessage

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

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

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

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

maxDiff

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

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

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

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

countTestCases()

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

defaultTestResult()

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

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

id()

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

shortDescription()

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

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

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

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

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

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

doCleanups()

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

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

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

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

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

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

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

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

classmethod doClassCleanups()

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

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

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

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

class unittest.IsolatedAsyncioTestCase(methodName='runTest')

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

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

coroutine asyncSetUp()

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

coroutine asyncTearDown()

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

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

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

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.

Утратившие актуальность псевдонимы

По историческим причинам некоторые из методов TestCase имели один или несколько псевдонимов, которые теперь устарели. В следующей таблице перечислены правильные имена вместе с их устаревшими псевдонимами:

Название метода

Утративший силу псевдоним

Утративший силу псевдоним

assertEqual()

failUnlessEqual

assertEquals

assertNotEqual()

failIfEqual

assertNotEquals

assertTrue()

failUnless

утверждение_

assertFalse()

failIf

assertRaises()

failUnlessRaises

assertAlmostEqual()

failUnlessAlmostEqual

assertAlmostEquals

assertNotAlmostEqual()

failIfAlmostEqual

assertNotAlmostEquals

assertRegex()

assertRegexpMatches

assertNotRegex()

assertNotRegexpMatches

assertRaisesRegex()

assertRaisesRegexp

Не рекомендуется, начиная с версии 3.1: Псевдонимы fail*, перечисленные во втором столбце, были устаревшими.

Не рекомендуется, начиная с версии 3.2: Псевдонимы assert*, перечисленные в третьем столбце, были устаревшими.

Не рекомендуется, начиная с версии 3.2: assertRegexpMatches и assertRaisesRegexp были переименованы в assertRegex() и assertRaisesRegex().

Не рекомендуется, начиная с версии 3.5: Имя assertNotRegexpMatches устарело в пользу assertNotRegex().

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

class unittest.TestSuite(tests=())

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

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

Объекты TestSuite ведут себя так же, как объекты TestCase, за исключением того, что они фактически не реализуют тест. Вместо этого они используются для объединения тестов в группы тестов, которые должны выполняться вместе. Для добавления тестов к экземплярам TestSuite доступны некоторые дополнительные методы:

addTest(test)

Добавьте TestCase или TestSuite в набор.

addTests(tests)

Добавьте все тесты из итерабельного набора экземпляров TestCase и TestSuite в этот набор тестов.

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

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

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

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

loadTestsFromTestCase(testCaseClass)

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

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

loadTestsFromModule(module, pattern=None)

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

Примечание

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

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

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

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

loadTestsFromName(name, module=None)

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

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

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

Метод опционально разрешает name относительно заданного module.

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

loadTestsFromNames(names, module=None)

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

getTestCaseNames(testCaseClass)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

testMethodPrefix

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

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

sortTestMethodsUsing

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

suiteClass

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

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

testNamePatterns

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

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

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

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

class unittest.TestResult

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

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

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

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

errors

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

failures

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

skipped

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

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

expectedFailures

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

unexpectedSuccesses

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

shouldStop

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

testsRun

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

buffer

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

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

failfast

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

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

tb_locals

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

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

wasSuccessful()

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

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

stop()

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

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

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

startTest(test)

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

stopTest(test)

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

startTestRun()

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

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

stopTestRun()

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

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

addError(test, err)

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

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

addFailure(test, err)

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

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

addSuccess(test)

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

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

addSkip(test, reason)

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

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

addExpectedFailure(test, err)

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

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

addUnexpectedSuccess(test)

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

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

addSubTest(test, subtest, outcome)

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

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

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

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

class unittest.TextTestResult(stream, descriptions, verbosity)

Конкретная реализация TestResult, используемая TextTestRunner.

Добавлено в версии 3.2: Ранее этот класс назывался _TextTestResult. Старое имя все еще существует как псевдоним, но оно устарело.

unittest.defaultTestLoader

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

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

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

По умолчанию этот бегунок показывает DeprecationWarning, PendingDeprecationWarning, ResourceWarning и ImportWarning, даже если они ignored by default. Предупреждения об износе, вызванные deprecated unittest methods, также имеют особый случай, и, если фильтры предупреждений 'default' или 'always', они будут появляться только один раз для каждого модуля, чтобы избежать слишком большого количества предупреждений. Это поведение можно отменить, используя опции Python -Wd или -Wa (см. Warning control) и оставив warnings в None.

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

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

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

_makeResult()

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

_makeResult() инстанцирует класс или вызываемый объект, переданный в конструкторе TextTestRunner в качестве аргумента resultclass. По умолчанию используется TextTestResult, если не указано resultclass. Класс result инстанцируется со следующими аргументами:

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)

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

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

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

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

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

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

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

Аргумент testLoader должен быть экземпляром TestLoader и по умолчанию имеет значение defaultTestLoader.

main поддерживает использование из интерактивного интерпретатора путем передачи аргумента exit=False. Это выводит результат на стандартный вывод без вызова sys.exit():

>>> from unittest import main
>>> main(module='test_module', exit=False)

Параметры failfast, catchbreak и buffer имеют тот же эффект, что и одноименные command-line options.

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

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

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

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

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

load_tests Протокол

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

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

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

load_tests(loader, standard_tests, pattern)

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

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

unittest.doModuleCleanups()

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

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

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

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

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

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

Существует несколько полезных функций для авторов фреймворков, позволяющих включить функциональность обработки control-c в тестовые фреймворки.

unittest.installHandler()

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

unittest.registerResult(result)

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

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

unittest.removeResult(result)

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

unittest.removeHandler(function=None)

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

@unittest.removeHandler
def test_signal_handling(self):
    ...
Вернуться на верх