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


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

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

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

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

См.также

Модуль doctest
Ещё один модуль поддержки тестирования с совсем другим подходом.
Простое тестирование в Smalltalk: с помощью шаблонов
Оригинальная статья Кента Бека о тестовых фреймворках с использованием шаблона, разработанного unittest.
pytest
Сторонняя среда unittest с облегчённым синтаксисом для написания тестов. Например, assert func(10) == 42.
Таксономия инструментов тестирования Python
Обширный список инструментов тестирования Python, включая фреймворки функционального тестирования и библиотеки объектов мок.
Тестирование в списке рассылки Python
Специальная группа для обсуждения тестирования и инструментов тестирования в Python.

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

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

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

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

import unittest

class TestStringMethods(unittest.TestCase):

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

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

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # проверить, что s.split не работает, если разделитель не
        # является строкой
        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.

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

-f, --failfast

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

-k

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

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

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

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

--locals

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

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

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

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

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

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

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

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

Обнаружение тестов реализовано в TestLoader.discover(), но также может использоваться из командной строки. Основное использование командной строки:

cd project_directory
python -m unittest discover

Примечание

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

У подкоманды discover следующие параметры:

-v, --verbose

Подробный вывод

-s, --start-directory directory

Каталог для запуска обнаружения (по умолчанию .)

-p, --pattern pattern

Шаблон для соответствия тестовым файлам (по умолчанию test*.py)

-t, --top-level-directory directory

Каталог верхнего уровня проекта (по умолчанию это начальный каталог)

Параметры -s, -p и -t могут быть переданы как позиционные аргументы в указанном порядке. Следующие две командные строки эквивалентны:

python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"

Помимо пути, в качестве начального каталога можно передать имя пакета, например myproject.subpackage.test. Указанное вами имя пакета будет затем импортировано, и его расположение в файловой системе будет использоваться в качестве начального каталога.

Осторожно

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

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

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

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

Изменено в версии 3.4: Обнаружение тестов поддерживает пакеты пространства имён.

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

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

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

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

import unittest

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

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

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

import unittest

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

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

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

Примечание

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

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

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

import unittest

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

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

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

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

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

class MyTestCase(unittest.TestCase):

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

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Тесты, работающие только для определенной версии библиотеки.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # код тестирования для Windows
        pass

    def test_maybe_skipped(self):
        if not external_resource_available():
            self.skipTest("external resource not available")
        # тестовый код, зависящий от внешнего ресурса
        pass

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

test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available'
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'

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

OK (skipped=4)

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

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

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

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

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

Легко создать свои пропускающие декораторы, создав декоратор, который вызывает skip() в тесте. Данный декоратор пропускает тест, если у переданного объекта нет определённого атрибута

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

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

@unittest.skip(reason)

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

@unittest.skipIf(condition, reason)

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

@unittest.skipUnless(condition, reason)

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

@unittest.expectedFailure

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

exception unittest.SkipTest(reason)

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

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

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

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

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

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

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

class NumbersTest(unittest.TestCase):

    def test_even(self):
        """
        Проверить, все ли числа от 0 до 5 четны.
        """
        for i in range(0, 6):
            with self.subTest(i=i):
                self.assertEqual(i % 2, 0)

вернёт следующий результат:

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

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

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

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

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

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

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

Тестовые кейсы

class unittest.TestCase(methodName='runTest')

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

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

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

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

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

setUp()

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

tearDown()

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

setUpClass()

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

@classmethod
def setUpClass(cls):
    ...

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

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

tearDownClass()

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

@classmethod
def tearDownClass(cls):
    ...

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

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

run(result=None)

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

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

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

skipTest(reason)

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

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

subTest(msg=None, **params)

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

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

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

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

debug()

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

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

Метод Что проверяет Новое в
assertEqual(a, b) a == b  
assertNotEqual(a, b) a != b  
assertTrue(x) bool(x) is True  
assertFalse(x) bool(x) is False  
assertIs(a, b) a is b 3.1
assertIsNot(a, b) a is not b 3.1
assertIsNone(x) x is None 3.1
assertIsNotNone(x) x is not None 3.1
assertIn(a, b) a in b 3.1
assertNotIn(a, b) a not in b 3.1
assertIsInstance(a, b) isinstance(a, b) 3.2
assertNotIsInstance(a, b) not isinstance(a, b) 3.2

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

assertEqual(first, second, msg=None)

Убедиться, что first и second равны. Если значения не совпадают, тест не пройден.

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

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

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

assertNotEqual(first, second, msg=None)

Убедиться, что first и second не равны. Если значения действительно совпадают, тест не пройден.

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

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

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

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

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

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

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

Убедиться, что expr является (или не является) None.

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

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

Убедиться, что member находится (или нет) в container.

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

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

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

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

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

Метод Проверяет, что Новое в
assertRaises(exc, fun, *args, **kwds) fun(*args, **kwds) вызывает exc  
assertRaisesRegex(exc, r, fun, *args, **kwds) fun(*args, **kwds) вызывает exc и сообщение соответствия регулярному выражению r 3.1
assertWarns(warn, fun, *args, **kwds) fun(*args, **kwds) вызывает warn 3.2
assertWarnsRegex(warn, r, fun, *args, **kwds) fun(*args, **kwds) вызывает warn и сообщение соответствия регулярному выражению r 3.2
assertLogs(logger, level) with блок логирует в logger с минимальным level 3.4
assertRaises(exception, callable, *args, **kwds)
assertRaises(exception, *, msg=None)

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

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

with self.assertRaises(SomeException):
    do_something()

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

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

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

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

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

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

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

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

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

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

или:

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

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

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

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

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

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

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

with self.assertWarns(SomeWarning):
    do_something()

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

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

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

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

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

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

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

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

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

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

или:

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

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

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

assertLogs(logger=None, level=None)

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

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

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

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

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

records

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

output

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

Пример:

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

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

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

Метод Проверяет, что Новое в
assertAlmostEqual(a, b) round(a-b, 7) == 0  
assertNotAlmostEqual(a, b) round(a-b, 7) != 0  
assertGreater(a, b) a > b 3.1
assertGreaterEqual(a, b) a >= b 3.1
assertLess(a, b) a < b 3.1
assertLessEqual(a, b) a <= b 3.1
assertRegex(s, r) r.search(s) 3.1
assertNotRegex(s, r) not r.search(s) 3.2
assertCountEqual(a, b) У a и b есть одинаковые элементы в одном и том же числе, независимо от их порядка. 3.2
assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)

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

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

Подача delta и places вызывает TypeError.

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

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

Проверить, что first соответственно >, >=, < или <=, чем second, в зависимости от имени метода. В противном случае тест не состоится:

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

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

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

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

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

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

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

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

assertCountEqual(first, second, msg=None)

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

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

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

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

addTypeEqualityFunc(typeobj, function)

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

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

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

Метод Используется для сравнения Новый в
assertMultiLineEqual(a, b) строки 3.1
assertSequenceEqual(a, b) последовательности 3.1
assertListEqual(a, b) списки 3.1
assertTupleEqual(a, b) кортежи 3.1
assertSetEqual(a, b) множества или замороженные множества 3.1
assertDictEqual(a, b) словари 3.1
assertMultiLineEqual(first, second, msg=None)

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

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

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

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

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

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

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

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

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

assertSetEqual(first, second, msg=None)

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

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

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

assertDictEqual(first, second, msg=None)

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

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

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

fail(msg=None)

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

failureException

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

longMessage

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

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

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

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

maxDiff

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

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

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

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

countTestCases()

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

defaultTestResult()

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

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

id()

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

shortDescription()

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

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

addCleanup(function, *args, **kwargs)

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

В случае сбоя setUp(), означающего, что tearDown() не вызывается, все добавленные функции очистки будут вызываться.

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

doCleanups()

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

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

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

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

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

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

В случае сбоя setUpClass(), означающего, что tearDownClass() не вызывается, все добавленные функции очистки будут вызываться.

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

classmethod doClassCleanups()

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

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

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

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

class unittest.IsolatedAsyncioTestCase(methodName='runTest')

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

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

coroutine asyncSetUp()

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

coroutine asyncTearDown()

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

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

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

run(result=None)

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

Пример, иллюстрирующий порядок:

from unittest import IsolatedAsyncioTestCase

events = []


class Test(IsolatedAsyncioTestCase):


    def setUp(self):
        events.append("setUp")

    async def asyncSetUp(self):
        self._async_connection = await AsyncConnection()
        events.append("asyncSetUp")

    async def test_response(self):
        events.append("test_response")
        response = await self._async_connection.get("https://example.com")
        self.assertEqual(response.status_code, 200)
        self.addAsyncCleanup(self.on_cleanup)

    def tearDown(self):
        events.append("tearDown")

    async def asyncTearDown(self):
        await self._async_connection.close()
        events.append("asyncTearDown")

    async def on_cleanup(self):
        events.append("cleanup")

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

После запуска теста events будет содержать ["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"].

class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)

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

Устаревшие псевдонимы

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

Название метода Устаревший псевдоним Устаревший псевдоним
assertEqual() failUnlessEqual assertEquals
assertNotEqual() failIfEqual assertNotEquals
assertTrue() failUnless assert_
assertFalse() failIf  
assertRaises() failUnlessRaises  
assertAlmostEqual() failUnlessAlmostEqual assertAlmostEquals
assertNotAlmostEqual() failIfAlmostEqual assertNotAlmostEquals
assertRegex()   assertRegexpMatches
assertNotRegex()   assertNotRegexpMatches
assertRaisesRegex()   assertRaisesRegexp

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

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

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

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

Группирующие тесты

class unittest.TestSuite(tests=())

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

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

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

addTest(test)

Добавить в комплект TestCase или TestSuite.

addTests(tests)

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

Это эквивалентно повторению tests с вызовом addTest() для каждого элемента.

TestSuite разделяет следующие методы с TestCase:

run(result)

Запустить тесты, связанные с этим набором, собрав результат в объект результата теста, переданный как result. Обратите внимание, что в отличие от TestCase.run(), TestSuite.run() требует передачи объекта результата.

debug()

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

countTestCases()

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

__iter__()

Доступ к тестам, сгруппированным по TestSuite, всегда осуществляется итерацией. Подклассы могут лениво предоставлять тесты, переопределяя __iter__(). Обратите внимание, что данный метод может вызываться несколько раз в одном множестве (например, при подсчете тестов или сравнении на равенство), поэтому тесты, возвращаемые повторными итерациями до TestSuite.run(), должны быть одинаковыми для каждой итерации вызова. После TestSuite.run() вызывающие не должны полагаться на тесты, возвращаемые этим методом, если вызывающий не использует подкласс, который переопределяет TestSuite._removeTestAtIndex() для сохранения ссылок на тесты.

Изменено в версии 3.2: В более ранних версиях TestSuite обращался к тестам напрямую, а не через итерацию, поэтому переопределения __iter__() было недостаточно для предоставления тестов.

Изменено в версии 3.4: В более ранних версиях TestSuite содержал ссылки на каждый TestCase после TestSuite.run(). Подклассы могут восстановить это поведение, переопределив TestSuite._removeTestAtIndex().

При типичном использовании объекта TestSuite метод run() вызывается TestRunner, а не тестовой системой конечного пользователя.

Загрузка и запуск тестов

class unittest.TestLoader

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

У объектов TestLoader есть следующие атрибуты:

errors

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

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

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

loadTestsFromTestCase(testCaseClass)

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

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

loadTestsFromModule(module, pattern=None)

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

Примечание

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

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

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

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

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

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

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

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

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

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

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

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

testMethodPrefix

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

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

sortTestMethodsUsing

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

suiteClass

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

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

testNamePatterns

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

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

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

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

class unittest.TestResult

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

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

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

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

errors

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

failures

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

skipped

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

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

expectedFailures

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

unexpectedSuccesses

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

shouldStop

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

testsRun

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

buffer

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

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

failfast

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

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

tb_locals

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

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

wasSuccessful()

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

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

stop()

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

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

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

startTest(test)

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

stopTest(test)

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

startTestRun()

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

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

stopTestRun()

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

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

addError(test, err)

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

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

addFailure(test, err)

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

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

addSuccess(test)

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

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

addSkip(test, reason)

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

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

addExpectedFailure(test, err)

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

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

addUnexpectedSuccess(test)

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

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

addSubTest(test, subtest, outcome)

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

Если outcomeNone, подтест прошёл успешно. В противном случае произошёл сбой, за исключением случая, когда 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)

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

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

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

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

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

_makeResult()

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

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

stream, descriptions, verbosity
run(test)

Данный метод является основным общедоступным интерфейсом к TextTestRunner. Данный метод принимает экземпляр TestSuite или TestCase. TestResult создаётся путём вызова _makeResult(), запускаются тесты, а результаты выводятся на стандартный вывод.

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

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

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

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

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

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

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

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

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

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

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

У параметров failfast, catchbreak и buffer тот же эффект, что и одноименные параметры командной строки.

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

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

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

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

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

Протокол load_tests

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

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

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

load_tests(loader, standard_tests, pattern)

где pattern проходит напрямую от loadTestsFromModule. По умолчанию это None.

Он должен возвращать TestSuite.

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

Типичная функция load_tests, которая загружает тесты из определённого набора классов TestCase, может выглядеть так:

test_cases = (TestCase1, TestCase2, TestCase3)

def load_tests(loader, tests, pattern):
    suite = TestSuite()
    for test_class in test_cases:
        tests = loader.loadTestsFromTestCase(test_class)
        suite.addTests(tests)
    return suite

Если обнаружение запускается в каталоге, содержащем пакет, либо из командной строки, либо путём вызова TestLoader.discover(), то пакет __init__.py будет проверен на наличие load_tests. Если данная функция не существует, обнаружение рекурсивно перейдет в пакет, как если бы это был просто другой каталог. В противном случае обнаружение тестов пакета будет оставлено на усмотрение load_tests, который вызывается со следующими аргументами:

load_tests(loader, standard_tests, pattern)

Она должна вернуть TestSuite, представляющий все тесты из пакета. (standard_tests будет содержать только тесты, собранные из __init__.py.)

Поскольку шаблон передаётся в load_tests, пакет может продолжить (и потенциально изменить) тестовое обнаружение. Так будет выглядеть функция load_tests «ничего не делать» для тестового пакета:

def load_tests(loader, standard_tests, pattern):
    # каталог верхнего уровня, кэшированный в экземпляре загрузчика
    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 больше не проверяет имена пакетов на соответствие pattern из-за невозможности совпадения имён пакетов с шаблоном по умолчанию.

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

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

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

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

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

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

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

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

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() вызывает исключение.

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

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

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

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

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

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

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

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

unittest.installHandler()

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

unittest.registerResult(result)

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

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

unittest.removeResult(result)

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

unittest.removeHandler(function=None)

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

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