Spec-Zone.ru › Python 3.11

unittest — Фреймворк для юнит-тестирования

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

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

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

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

тестовая среда

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

тестовый случай

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

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

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

тестовый прогон

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

См. также

Module doctest

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

Simple Smalltalk Testing: With Patterns

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

pytest

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

Таксономия инструментов тестирования Python

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

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

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

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

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

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

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

import unittest

class TestStringMethods(unittest.TestCase):

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

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

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

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

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

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

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

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

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

OK

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

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

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

OK

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

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

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

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

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

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

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

python -m unittest tests/test_something.py

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

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

python -m unittest -v test_module

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

python -m unittest

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

python -m unittest -h

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

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

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

-b, --buffer

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

-c, --catch

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

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

-f, --failfast

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

-k

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

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

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

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

--locals

Отобразить локальные переменные в отладке.

Новое в версии 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 protocol.

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

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

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

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

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

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

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

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

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

import unittest

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

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

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

import unittest

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

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

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

Примечание

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

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

Аналогично, мы можем предоставить метод tearDown(), который выполняет завершающие действия после выполнения тестового метода:

import unittest

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

Новая версия 3.1.

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

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

Базовый пропуск выглядит следующим образом:

class MyTestCase(unittest.TestCase):

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

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # windows specific testing code
        pass

    def test_maybe_skipped(self):
        if not external_resource_available():
            self.skipTest("external resource not available")
        # test code that depends on the external resource
        pass

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

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

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

OK (skipped=4)

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

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

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

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

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

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

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

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

@unittest.skip(reason)

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

@unittest.skipIf(condition, reason)

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

@unittest.skipUnless(condition, reason)

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

@unittest.expectedFailure

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

exception unittest.SkipTest(reason)

Это исключение поднимается для пропуска теста.

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

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

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

Новая версия 3.4.

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

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

class NumbersTest(unittest.TestCase):

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

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

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

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

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

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

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

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

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

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

class unittest.TestCase(methodName='runTest')

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

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

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

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

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

setUp()

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

tearDown()

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

setUpClass()

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

@classmethod
def setUpClass(cls):
    ...

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

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

tearDownClass()

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

@classmethod
def tearDownClass(cls):
    ...

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

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

run(result=None)

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

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

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

skipTest(reason)

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

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

subTest(msg=None, **params)

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

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

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

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

debug()

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

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

Метод

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

Добавлен в

assertEqual(a, b)

a == b

assertNotEqual(a, b)

a != b

assertTrue(x)

bool(x) is True

assertFalse(x)

bool(x) is False

assertIs(a, b)

a is b

3.1

assertIsNot(a, b)

a is not b

3.1

assertIsNone(x)

x is None

3.1

assertIsNotNone(x)

x is not None

3.1

assertIn(a, b)

a in b

3.1

assertNotIn(a, b)

a not in b

3.1

assertIsInstance(a, b)

isinstance(a, b)

3.2

assertNotIsInstance(a, b)

not isinstance(a, b)

3.2

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

assertEqual(first, second, msg=None)

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

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

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

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

assertNotEqual(first, second, msg=None)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Метод

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

Добавлено в

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

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

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

fun(*args, **kwds) вызывает exc, и сообщение соответствует регулярному выражению r

3.1

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

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

3.2

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

fun(*args, **kwds) вызывает warn, и сообщение соответствует регулярному выражению r

3.2

assertLogs(logger, level)

Блок with записывает в журнал logger с минимальным уровнем level

3.4

assertNoLogs(logger, level)

The with block does not log on

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

3.10

assertRaises(exception, callable, *args, **kwds)
assertRaises(exception, *, msg=None)

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

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

with self.assertRaises(SomeException):
    do_something()

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

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

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

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

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

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

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

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

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

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

или:

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

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

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

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

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

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

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

with self.assertWarns(SomeWarning):
    do_something()

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

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

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

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

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

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

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

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

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

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

или:

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

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

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

assertLogs(logger=None, level=None)

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

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

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

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

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

records

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

output

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

Пример:

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

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

assertNoLogs(logger=None, level=None)

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

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

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

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

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

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

Метод

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

Добавлена в

assertAlmostEqual(a, b)

round(a-b, 7) == 0

assertNotAlmostEqual(a, b)

round(a-b, 7) != 0

assertGreater(a, b)

a > b

3.1

assertGreaterEqual(a, b)

a >= b

3.1

assertLess(a, b)

a < b

3.1

assertLessEqual(a, b)

a <= b

3.1

assertRegex(s, r)

r.search(s)

3.1

assertNotRegex(s, r)

not r.search(s)

3.2

assertCountEqual(a, b)

a и b имеют одинаковые элементы в одинаковом количестве, независимо от их порядка.

3.2

assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)

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

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

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

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

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

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

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

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

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

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

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

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

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

Добавлена в версии 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 символов. Методы assert, на которые влияет этот атрибут, — 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.

enterContext(cm)

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

Новое в версии 3.11.

doCleanups()

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

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

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

Новое в версии 3.1.

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

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

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

Новое в версии 3.8.

classmethod enterClassContext(cm)

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

Новое в версии 3.11.

classmethod doClassCleanups()

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

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

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

Новое в версии 3.8.

class unittest.IsolatedAsyncioTestCase(methodName='runTest')

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

Новое в версии 3.8.

coroutine asyncSetUp()

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

coroutine asyncTearDown()

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

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

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

coroutine enterAsyncContext(cm)

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

Новое в версии 3.11.

run(result=None)

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

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

from unittest import IsolatedAsyncioTestCase

events = []


class Test(IsolatedAsyncioTestCase):


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

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

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

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

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

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

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

После выполнения теста, events будет содержать ["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"].

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

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

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

По историческим причинам некоторые методы 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)

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

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

loadTestsFromModule(module, pattern=None)

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

Примечание

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

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

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

Изменено в версии 3.5: Недокументированный и неофициальный необязательный аргумент 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.4: start_dir может быть пространством имён.

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

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

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

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

testMethodPrefix

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

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

sortTestMethodsUsing

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

suiteClass

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

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

testNamePatterns

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

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

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

Новое в версии 3.7.

class unittest.TestResult

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

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

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

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

errors

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

failures

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

skipped

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

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

expectedFailures

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

unexpectedSuccesses

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

shouldStop

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

testsRun

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

buffer

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

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

failfast

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

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

tb_locals

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

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

wasSuccessful()

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

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

stop()

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

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

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

startTest(test)

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

stopTest(test)

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

startTestRun()

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

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

stopTestRun()

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

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

addError(test, err)

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

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

addFailure(test, err)

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

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

addSuccess(test)

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

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

addSkip(test, reason)

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

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

addExpectedFailure(test, err)

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

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

END_OF_DOCUMENT_MARKER
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 не указан, используется 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):
    # top level directory cached on loader instance
    this_dir = os.path.dirname(__file__)
    package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
    standard_tests.addTests(package_tests)
    return standard_tests

Изменено в версии 3.5: Обнаружение больше не проверяет имена пакетов на соответствие pattern из-за невозможности совпадения имён пакетов с шаблоном по умолчанию.

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

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

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

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

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

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

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

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

setUpClass и tearDownClass

Эти методы должны быть реализованы как методы класса:

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()

Если вы хотите, чтобы setUpClass и tearDownClass базовых классов вызывались, то вы должны вызвать их самостоятельно. Реализации в TestCase пустые.

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

setUpModule и tearDownModule

Эти функции должны быть реализованы как функции:

def setUpModule():
    createConnection()

def tearDownModule():
    closeConnection()

Если в setUpModule возникает исключение, то тесты в модуле не выполняются, и tearDownModule не выполняется. Если исключение является исключением SkipTest, то модуль будет отметен как пропущенный вместо ошибки.

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

unittest.addModuleCleanup(function, /, *args, **kwargs)

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

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

Новое в версии 3.8.

classmethod unittest.enterModuleContext(cm)

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

Новое в версии 3.11.

unittest.doModuleCleanups()

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

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

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

Новое в версии 3.8.

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

Новая в версии 3.2.

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

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

Есть несколько служебных функций для авторов фреймворков, чтобы включить функциональность обработки Ctrl+C в рамках тестов.

unittest.installHandler()

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

unittest.registerResult(result)

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

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

unittest.removeResult(result)

Удалить зарегистрированный результат. После удаления результата, stop() больше не будет вызываться для этого объекта результата в ответ на нажатие Ctrl+C.

unittest.removeHandler(function=None)

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

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

© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/unittest.html

Spec-Zone.ru

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