unittest — Фреймворк тестирования юнитов Python
Фреймворк тестирования юнитов Python, иногда называемый «PyUnit», является версией Python для JUnit от Kent Beck и Erich Gamma. JUnit, в свою очередь, является Java версией фреймворка тестирования от Kent’а для Smalltalk. Каждый из них является стандартом де факто для своего языка.
unittest в Python поддерживает автоматизацию тестов, использование общего кода для настройки и завершения тестов, объединение тестов в коллекции и отделение тестов от фреймворка для вывода информации. Модуль unittest предоставляет классы, которые облегчают поддержку этих свойств для наборов тестов.
Для того, чтобы достичь этого, unittest поддерживает некоторые важные концепции:
испытательный стенд испытательный стенд (test fixture) представляет подготовку, необходимой, чтобы выполнить один или более тестов и все необходимые действия по отчистке. Это может включать, например, создание временных или проксирующих баз данных или запуск серверного процесса. тестовый случай тестовый случай (test case) — минимальный юнит тестирования. Он проверяет ответы для разных наборов данных. unittest предоставляет базовый класс TestCase, который можно использовать для создания новых тестовых случаев. набор тестов набор тестов (test suite) является набором тестовых случаев, наборов тестов или и того и другого. Он используется для объединения тестов, которые должны быть исполнены вместе. исполнитель тестов исполнитель тестов (test runner) является компонентом, который управляет выполнением тестов и представляет пользователю результат. Исполнитель может использовать графический или текстовый интерфейс или возвращать специальное значение, которое сообщает о результатах выполнения тестов.
Понятия тестового случая и испытательного стенда поддерживаются классами TestCase и FunctionTestCase; первый должен быть использован для создания новых тестов, а последний может быть использован для интеграции существующих тестов с фреймворком, основанном на unittest. При создании испытательного стенда при помощи TestCase, методы setUp() tearDown() могут быть переопределены для инициализации стенда и очистки после тестов. Вместе с FunctionTestCase, существующие функции могут быть переданы в конструктор для этих целей. Во время выполнения теста, сперва выполняется инициализация стенда, если она проходит успешно, метод очистки выполняется после выполнения каждого теста, вне зависимости от результата теста. Каждый экземпляр TestCase будет использоваться для запуска одного тестового метода, так что стенд создаётся для каждого теста.
Набор тестов реализуется классом TestSuite. Этот класс позволяет объединять отдельные тесты и наборы тестов; когда выполняется набор тестов, то выполняются все тесты добавленные в набор и в его дочерние наборы.
Выполнитель тестов — это объект, который предоставляет всего один метод, run(), который принимает объект TestCase или TestSuite в качестве параметра и возвращает результирующий объект. Класс TestResult используется как результирующий объект. unittest предоставляет класс TextTestRunner как пример выполнителя тестов, который по умолчанию выводит итог в стандартный поток ошибок. Альтернативные выполнители тестов могут быть реализованы и для других окружений (например, графических) без необходимости наследования из определённого класса.
unittest2: Обратное портирование новых возможностей unittest для Python 2.4-2.6
В unittest для Python 2.7 было добавлено много новых возможностей, включая поиск тестов. unittest2 позволяет использовать эти возможности в более ранних версиях Python.
Основные примеры
Модуль unittest предоставляет бокатый набор инструментов для создания и запуска тестов. Этот раздел демонстрирует, что небольшой набор этих инструментов удволетвоярет большинство ваших потребностей.
Вот короткий скрипт для тестирования трёх функций из модуля random:
Набор тестов создаётся при помощи подкласса unittest.TestCase. Три отдельных теста определены в методах, чьи имена начинаются с test. Это соглашение об именах сообщает выполнителю тестов о том, какие методы содержат тесты.
Задачей каждого теста является вызов assertEqual() для проверки ожидаемого вывода; assertTrue() для проверки условий; или assertRaises() для проверки того, что) возбуждается ожидаемое исключение. Эти методы используются вместо выражения assert, так что выполнитель тестов может собирать все результаты тестов и создавать отчёт.
Когда определён метод setUp(), выполнитель тестов запустит этот метод перед каждым тестом. Похожим образом если определён метод tearDown(), выполнитель тестов будет вызывать этот метод после каждого теста. В нашем примере setUp() использовался для создания свежей последовательности для каждого теста.
Финальный блок показывает простой способ выполнить тесты. unittest.main() предоставляет интерфейс командной строки к тестовому скрипту. Когда он запускается из командной строки, скрипт из примера выше даст вывод вроде этого:
Вместо unittest.main(), есть другие способы запуска тестов с более точным управлением, более подробным выводом, и для которых не обязательно использовать командную строку. Например, последние две строки можно заменить следующими детальным управление:
Запустив полученный скрипт в интерпретаторе или в другом скрипте, мы получим следующий вывод:
Примеры выше показывают наиболее стандартный способ использования возможностей unittest, которые позволяют удовлетворить ваши повседневные потребности. Остальная часть документации описывает полный набор всех возможностей.
Интерфейс командной строки
Модуль unittest может быть использован из командной строки для запуска тестов из модулей, классов или даже отдельных методов:
Вы можете использовать список с любой комбинацией имён модулей и полных имён классов или методов.
Вы можете запускать тесты в более детальном режиме при помощи флага -v:
Для получения полного списка всех опций командной строки:
Changed in version 2.7: В ранних версиях можно было запускать только отдельные методы, но не модули и классы.
Опции командной строкиunittest поддерживает следующие опции командной строки:
-b, —buffer Потоки стандартного вывода и стандартного вывода ошибок буфферизуются во время выполнения тестов. Вывод во время прохождения тестов сбрасывается. Вывод обрабатывается нормально если тест не проходит или выдаёт ошибку и к нему добавляется сообщение об ошибке. -c, —catch Control-C во время выполнения теста ожидает завершения текущего теста и затем сообщает результаты на данный момент. Второе нажатие control-C вызывает обычное исключение KeyboardInterrupt.
Смотрите Обработка сигналов где описываются функции, которые предоставляют эту функциональность. -f, —failfast Завершает выполнение теста на первой ошибке.
New in version 2.7: Были добавлены опции командной строки -b, -c и -f.
Командная строка так же может быть использована для поиска тестов, запуска всех тестов в проекте или набора тестов.
Поиск тестов
New in version 2.7.
Unittest поддерживает простое обнаружение тестов. Для этого все модули импортируемы как модули или пакеты из каталога проекта верхнего уровня (то есть, имена их файлов должны быть корректными идентификаторами).
Поиск тестов реализован в TestLoader.discover(), но может быть использован и из командной строки. Пример использования:
Подкоманда discover имеет следующие опции:
-v, —verbose Подробный вывод -s, —start-directory directory Каталог для начала поиска (по умолчанию .) -p, —pattern pattern Шаблон, которому должны соответствовать тестовые файлы (по умолчанию test*.py) -t, —top-level-directory directory Каталог верхнего уровня проека (по умолчанию — стартовый каталог)
Опции -s, -p, и -t могут быть переданы как позиционные аргументы в этом порядке. Следущие две строки эквивалентны:
Вместо пути можно передать имя пакета, например myproject.subpackage.test, вместо начального каталога. Имя пакета, которое вы указываете будет импортировано, а его расположение в файловой системе будет использовано как начальный каталог.
Обнаружение теста загружает тесты импортируя их. После того, как были найдены все тестовые файлы в стартовом каталоге, их пути преобразуются в имена пакетов для импорта. Например, foo/bar/baz.py будет импортирован как foo.bar.baz.
Если у вас есть глобально установленный пакет и вы пытаетесь обнаружить тесты в другой копии пакета, тогда импорт возможно произойдёт из неверного места. Если это происходит, обнаружитель тестов предупредит вас об этом и завершит работу.
Если вы указываете в качестве стартового каталога имя пакета, а не путь к каталогу, тогда обнаружитель подразумевает, что откуда бы не импортировался пакет, он импортируется из верного места, так что вы не получите предупреждения.
Модули и пакеты тестов могут настроить загрузку и поиск тестов при помощи протокола load_tests_.
Организация тестового кода
Основные строительные блоки юнит-тестов — тестовый случай — одиночные сценарии, которые должны быть настроены и проверены на корректное выполнение. В unittest, тестовые случаи представлены экземплярами класса TestCase unittest‘а. Для того, чтобы сделать свой тестовый случай вы должны написать подкласс TestCase, или использовать FunctionTestCase.
Экземпляр класса-наследника от TestCase является объектом, который может запустить один тестовый метод вместе с опциональным кодом настройи и очистки.
Тестовый код экземпляра TestCase должен быть полностью самодостаточным, так что его можно запускать в изоляции или в произвольной комбинации с любым другим количеством тестовых случаев.
Простейший подкласс TestCase просто переопределяет метод runTest() для того, чтобы выполнять конкретный код теста:
Обратите внимание, что для того, чтобы протестировать что-то мы используем один из assert*() методов, предоставляемых базовым классом TestCase. Если тест не удаётся, будет возбуждено исключение, и unittest пометит этот тестовый случай как failure. Все другие исключения будут трактоваться как errors. Это поможет вам определить, в чём кроется проблема: failures возникает при некорректом результате — вы ожидали 6, а получили 5. Errors возникают из-за ошибок в коде, например, TypeError при некорректном вызове функции.
Способ запуска тестового случая будет описан ниже. На данный момент, обратите внимание, что для создания экземпляра такого тестового случая, мы вызываем конструктор без аргументов:
Далее, таких тестовых случаем может быть несколько, а их настройка может быть одинаковой. В таком случае, создание Widget в каждом из 100 тестовых случаев для подклассов может означать ненужное дублирование.
К счастью, мы можем вынести настроечный код, реализовав метод setUp(), который автоматически вызывается фреймворком, когда мы запускаем тест:
Если метод setUp() возбуждает исключение во время выполнения теста, фреймворк предполагает, что тест содержит существенную ошибку и метод runTest() даже не будет запущен.
Похожим образом, мы можем предоставить метод tearDown(), который выполняется после метода runTest():
Если setUp() выполняется успешно, метод tearDown() будет выполнен вне зависимости от метода runTest().
Такое рабочее окружение для тестирования называется стендом.
Достаточно часто несколько маленьких тестов используют один и тот же стенд. В этом случае мы приходим к созданию большого числа маленьких однометодовых подклассов SimpleWidgetTestCase, таких как DefaultWidgetSizeTestCase. Это требует уйму времени и утомительно, так что в том же духе, что и JUnit, unittest предоставляет похожий механизм:
Тут мы не использовали метод runTest(), а вместо него релизовали два других тестовых метода. Экмзепляр класса теперь запустит каждый из test_*() методов, где self.widget будет создан и разрушен отдельно для каждого экземпляра. Когда мы создаём экземпляр, мы должны определить тестовый метод, который он будет выполнять. Мы делаем это передвая имя метода в конструктор:
Экземпляры тестового случая группируются вместе в соответствии с функционалом, который они тестирюут. unittest предоставляет для этого механизм: набор тестов, предоставленный классом TestSuite unittest‘а:
Для того, чтобы проще запускать тесты, как мы увидим позже, хорошей идеей будет предоставить в каждом тестовом модуле вызываемый объект, который возвращает уже готовый набор тестов:
Так как создание подкласса TestCase с многими похоже названными функциями широко распространено, unittest предоставляет класс TestLoader, который может быть использован для создания набора тестов и наполнения его тестами. Например:
создаст набор тестов, который выполнит WidgetTestCase.test_default_size() и WidgetTestCase.test_resize. TestLoader использует префикс имени метода ‘test’ для идентификации тестовых методов.
Обратите внимание, что порядок, в котором тесты будут запущены определяется сортировкой имён тестовых функций согласно встроенному порядку сортировки строк.
Часто бывает желательно сгруппировать наборы тестов, чтобы запускать тесты для всей системы одновременно. Это легко сделать, так как экземпляры TestSuite могут быть добавлены в TestSuite, как и экземпляры TestCase:
Вы можете расположить определения тестовых случаев и наборов тестов в том же модуле, что и код, который они тестируют (например, в файл widget.py), но есть преимущества в расположении теста в отдельном модуле, например в test_widget.py:
- Тестовый модуль может быть запущен отдельно из командной строки.
- Тестовый код легче отделить от поставляемого кода.
- Гораздо меньше соблазна изменить тестовый код, чтобы он соответствовал тестируемому коду без весомой причины.
- Тестовый код должен меняться гораздо реже, чем тестируемый.
- Тестовый код можно проще подвергнуть рефакторингу.
- Тесты для модулей, написаных на С, должны быть отделены от модулей, так почему бы не сделать так со всеми тестами?
- Если стратегия тестирования изменяется, то нет нужды менять исходный код.
Повторное использование тестового кода
Некоторые пользователи могут обнаружить, что у них уже есть тестовый код, который они хотели бы запустить из под unittest, без того, чтобы преобразовывать все тестовые функции в подклассы TestCase.
По этой причине unittest предоставляет класс FunctionTestCase. Этот подкласс класса TestCase может быть использован как обёртка для существующих тестовых функций. Так же для него есть функции настройки и очистки.
Предположим, у нас есть следующая тестовая функция:
для которой можно создать эквивалентный экземпляр тестового случая:
Если есть дополнительные методы настройки и очистки, которые должны быть вызваны как часть теста, то их тоже можно указать:
Для того, чтобы облегчить миграцию существующих тестовых наборов, unittest позволяет тестам возбуждать AssertionError для обозначения падения теста. Однако, рекомендуется вместо этого явно использовать методы TestCase.fail*() и TestCase.assert*(), так как будущие версии unittest могут трактовать AssertionError по другому.
Хотя FunctionTestCase может быть использован для быстрой конвертации существующих тестов в систему, основанную на unittest, делать так не рекомендуется. Затраченное время на создание соответствующего подкласса TestCase позволит вам позже проще проводить рефакторинг теста.
В некоторых случаях существующие тесты могут быть написаны при помощи модуля doctest. Этот модуль предоставляет класс DocTestSuite, который может автоматически создать экземпляр класса unittest.TestSuite из существующих тестов, основанных на doctest.
Игнорирование тестов и ожидаемые ошибки
New in version 2.7.
Unittest поддерживает игнорирование отдельных тестовых методов и даже целых тестовых классов. Кроме того, он поддерживает возможность пометить тест как «ожидающий ошибку», что означает, что тест сломан и не будет пройден, но не должен учитываться как не пройденный экземпляром TestResult.
Пропуск теста делается просто использованием skip() decorator или одного из его условных вариантов.
Игнорирование в простом случае выглядит так:
Вот вывод этих примеров в «говорливом» режиме:
Классы можно пропускать так же как и методы:
TestCase.setUp() тоже может пропустить тесты. Это полезно в случае, если ресурсы, необходимые для настройки теста не доступны.
Ожидание ошибки обеспечивается при помощи декторатора expectedFailure():
Достаточно легко запустить свой собственный декоратор пропуска тестов, используя вызов skip() для тестов, которые вы хотите пропустить. Вот такой декоратор будет пропускать тесты, пока полученный объект не будет иметь определённый атрибут:
Следующие декораторы реализуют пропуск тестов и ожидание ошибок:
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().
Классы и функции
Этот раздел подробно описывает API модуля unittest.
Test casesКаждый экземпляр TestCase будет запускать один тестовый метод: метод и именем methodName. Если вы помните, у нас уже был пример чего-то вроде этого:
Тут мы создаём два экземпляра класса WidgetTestCase, каждый из которых запускает один тест.
methodName по умолчанию является runTest().
Экземпляры TestCase предоставляют три группы методов: одна группа используется для запуска тестов, другая используется реализацией теста для проверки условий и сообщейний об ошибках, а некоторые методы позволяют собирать информацию о самих тесатх.
Методы в первой группе (запуск тестов):
setUp() Метод вызывается для подготовки тестового стенда. Он вызывается непосредственно перед вызовом тестового метода; все исключения вызываемыми этим методом будут трактоваться как ошибки, а не как провал теста. По умолчанию ничего не делает. tearDown() Метод вызывается сразу после вызова тестового метода и сохранения результата. Он вызывается даже если тестовый метод вызвал исключение, так что его реализация в подклассе должна особенно внимательно относиться к проверке внутреннего состояния. Все исключения, вызванные этим методом будут трактоваться как ошибки, а не как провал теста. Этот метод вызывается только если setUp() завершился успешно, вне зависимости от результата тестового метода. Реализация по умолчанию не делает ничего. setUpClass() Метод класса выызваемый перед запуском тестов в классе. setUpClass вызывается только с одним аргументом — классом, и должен быть декорированным при помощи classmethod():
New in version 2.7. tearDownClass() Метод класса, вызываемый после тестов в классе. tearDownClass вызывается только с одним аргументом — классом, и должен быть декорирован при помощи classmethod():
Более подробно смотрите в Стенды класса и модуля .
New in version 2.7. run(result=None) Запускает тест, собирает резльутат в объект результата теста, полученный через result. Если result не указан или равен None, создаётся временный объект результата (при помощи вызова метода defaultTestResult()), который затем и используется. Объект результата не возвращается вызвашему run().
Тот же самый эффект может быть достигнут простым вызовом экземпляра TestCase. skipTest(reason) Вызов этого метода в тестовом методе или в setUp() приведёт к пропуску теста. Более подробно смотрите в Игнорирование тестов и ожидаемые ошибки.
New in version 2.7. debug() Запуск теста без сбора результата. Это позволяет исключениям, которые вызываются тестом быть переданными вызывающему объекту и его можно использовать для поддержки запуска теста в режиме отладки.
Класс TestCase предоставляет некоторое количество методов для проверки и сообщения об ошибках, такие как:
Метод Проверяет что Начиная с 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 2.7 assertIsNot(a, b) a is not b 2.7 assertIsNone(x) x is None 2.7 assertIsNotNone(x) x is not None 2.7 assertIn(a, b) a in b 2.7 assertNotIn(a, b) a not in b 2.7 assertIsInstance(a, b) isinstance(a, b) 2.7 assertNotIsInstance(a, b) not isinstance(a, b) 2.7
Все методы assert (кроме assertRaises(), assertRaisesRegexp()) принимают аргумент msg, который используется в качестве сообщения об ошибке при неудаче теста (смотри также longMessage).
assertEqual(first, second, msg=None) Проверяет, что first и second равны. Елси они не равны — тест не пройден.
Кроме того, если first и second одного и того же типа и принадлежат list, tuple, dict, set, frozenset, unicode или любому другому типу, который является подклассом, зарегистрированным при помощи addTypeEqualityFunc(), будет вызвана специфичная для этого типа функция сравнения для того, чтобы получить более детальное сообщение об ошибке (смотрите также список методов специфичных для типов).
Changed in version 2.7: Добавлен автоматический вызов функций сравнения, специфичных для определённого типа. 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 вычисляются (или не вычисляются) в тот же самый объект.
New in version 2.7. assertIsNone(expr, msg=None) assertIsNotNone(expr, msg=None) Проверяет, что expr является (или нет) None.
New in version 2.7. assertIn(first, second, msg=None) assertNotIn(first, second, msg=None) Проверяет, что first (не) находится в second.
New in version 2.7. assertIsInstance(obj, cls, msg=None) assertNotIsInstance(obj, cls, msg=None) Проверяет, что obj (не) является экземпляром класса cls (который может быть классом или кортежем классов, как это поддерживается функцией isinstance()). Для того, чтобы проверить точное соответствие типу используйте assertIs(type(obj), cls).
New in version 2.7.
Кроме того, можно проверить, какое исключение или предупреждение было выдано при помощи следующих методов:
Метод Проверяет что Начиная с assertRaises(exc, fun, *args, **kwds) fun(*args, **kwds) вызывает exc assertRaisesRegexp(exc, r, fun, *args, **kwds) fun(*args, **kwds) вызывает exc и сообщение соответствует regex r 2.7 assertRaises(exception, callable, *args, **kwds) assertRaises(exception) Проверяет, что при вызове callable с переданными позиционными или именованными аргументами вызовет исключение. Тест считается пройденным, если вызывается исключение exception, ошибкой будет считаться вызов другого исключения, а провалом теста — если исключение не вызвано. Для того, чтобы перехватить группу исключений, можно передать в качестве exception кортеж, который содержит эти исключения.
Если передан только аргумент exception, возвращается менеджер контекста, так что код для тестирования можно записать прямо в строку, вместо того, чтобы его оформлять в виде функции:
Менеджер контекста сохраняет объект перехваченного исключения в своём атрибуте exception. Это может быть полезным, если мы хотим провести дополнительные проверки возбуждённого исключения:
Changed in version 2.7: Добавлена возможность использовать assertRaises() как менеджер контекста. assertRaisesRegexp(exception, regexp, callable, *args, **kwds) assertRaisesRegexp(exception, regexp) Похож на assertRaises(), но кроме этого проверяет, что regexp соответствует строковому представлению вызванного исключения. regexp может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, которое можно использовать в re.search(). Например:
New in version 2.7.
Есть и другие методы, которые используются для более специфических проверок, таких как:
Метод Проверяет что Начиная с assertAlmostEqual(a, b) round(a-b, 7) == 0 assertNotAlmostEqual(a, b) round(a-b, 7) != 0 assertGreater(a, b) a > b 2.7 assertGreaterEqual(a, b) a >= b 2.7 assertLess(a, b) a < b 2.7 assertLessEqual(a, b) a <= b 2.7 assertRegexpMatches(s, r) r.search(s) 2.7 assertNotRegexpMatches(s, r) not r.search(s) 2.7 assertItemsEqual(a, b) sorted(a) == sorted(b) и работает с unhashable объектами 2.7 assertDictContainsSubset(a, b) все пары key/value из a присутствуют в b 2.7 assertAlmostEqual(first, second, places=7, msg=None, delta=None) assertNotAlmostEqual(first, second, places=7, msg=None, delta=None) Проверяет, что first и second приблизительно (или не приблизительно) равны, вычисляя разницу и округляя её до указанного в аргументе places знака после запятой (по умолчанию 7) и сравнивая эту разницу с 0. Обратите внимание, что этот метод округляет значение до заданного знака, а не до значимого знака (как функция round()).
Если указан аргумент delta вместо places, то разница между first и second должна быть меньше (или больше) или равна delta.
Указание и delta и places вызовет TypeError.
Changed in version 2.7: 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, в зависимости от имени метода. Если нет, то тест не проходит:
New in version 2.7. assertRegexpMatches(text, regexp, msg=None) Проверяет, что regexp соответствует text. В случае не прохождения теста, сообщение об ошибке будет содержать шаблон и text (или шаблон и часть текста, которая внезапно совпала). regexp может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, которую можно использовать для re.search().
New in version 2.7. assertNotRegexpMatches(text, regexp, msg=None) Проверяет, что поиск regexp не обрануживает соответствия в text. В случае не прохождения теста, сообщение об ошибке будет содержать шаблон и ту часть текста, которая совпала. regexp может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, которую можно использовать для re.search().
New in version 2.7. assertItemsEqual(actual, expected, msg=None) Проверяет, что последовательность expected содержит те же элементы, что и actual, вне зависимости от их порядка. Если это не так, то будет выведено сообщение об ошибке, содержащее разницу между последовательностями.
Повторяющиеся элементы не игнорируются при сравнении actual и expected. Проверяется, что каждого элемента есть ровно такое же количество в каждой последовательности. Это эквивалент assertEqual(sorted(expected), sorted(actual)), но он так же работает с последовательностями нехешируемых объектов.
В Python 3 этот метод называется assertCountEqual.
New in version 2.7. assertDictContainsSubset(expected, actual, msg=None) Проверяет, что пары key/value в словаре actual являются надмножеством тех, что есть в expected. Иначе будет выведено сообщение об ошибке, содержащее отсутствующие ключи и не соответствующие значения.
New in version 2.7.
Deprecated since version 3.2.
Метод assertEqual() передаёт проверку равенства объектов одного типа различным типо-специфическим методам. Этим методы уже реализованы для для большей части встроенных типов, но можно зарегистрировать и свои методы при помощи addTypeEqualityFunc():
addTypeEqualityFunc(typeobj, function) Регистрирует специфичный для типа метод, вызываемый assertEqual() для проверки того, что два объекта одного типа typeobj (не подклассы) равны. function должна принимать два позиционных аргумента и третий именованный msg=None, как и assertEqual(). Она должна вызывать self.failureException(msg) при обнаружении неравенства между первыми двумя параметрами – возможно предоставляя полезную информацию и объясняя детально причины неравенства в сообщении об ошибке.
New in version 2.7.
Список специфичных методов для типов, автоматически используемых assertEqual() приведён в следующей таблице. Обратите внимание, что обычно нет необходимости вызывать эти методы напрямую.
Метод Используется для сравнения Начиная с assertMultiLineEqual(a, b) strings 2.7 assertSequenceEqual(a, b) sequences 2.7 assertListEqual(a, b) lists 2.7 assertTupleEqual(a, b) tuples 2.7 assertSetEqual(a, b) sets or frozensets 2.7 assertDictEqual(a, b) dicts 2.7 assertMultiLineEqual(first, second, msg=None) Проверяет, что многострочная строка first равна строке second. Если они не равны, то разница между двумя строками будет включена в сообщение об ошибке. Этот метод используется по умолчанию при сравнении строк при помощи assertEqual().
New in version 2.7. assertSequenceEqual(seq1, seq2, msg=None, seq_type=None) Проверяет, что две последовательности равны. Если указан seq_type, то и seq1 и seq2 должны быть экземплярами seq_type или будет возбуждено исключение. Если последовательности отличаются, то будет выведено сообщение об ошибке, содержащее разницу между двумя последовательностями.
Этот метод не вызывается напрямую методом assertEqual(), но он используется для реализации assertListEqual() и assertTupleEqual().
New in version 2.7. assertListEqual(list1, list2, msg=None) assertTupleEqual(tuple1, tuple2, msg=None) Проверяет, что два списка или корежа равны. В противном случае будет выдано сообщение об ошибке, содержащее разницу между двумя последовательностями. Ошибка так же появится в случае, если какой-либо параметр не того типа. Эти методы по умолчанию используются для сравнения списков и кортежей методом assertEqual().
New in version 2.7. assertSetEqual(set1, set2, msg=None) Проверяет, что два множества равны. Иначе будет показано сообщение об ошибке, которое содержит разницу между двумя множествами. Этот метод используется по по умолчанию для сравения двух множеств или frozenset assertEqual().
Тест не будет пройденным если set1 или set2 не имеет метода set.difference().
New in version 2.7. assertDictEqual(expected, actual, msg=None) Проверяет, что два словаря равны. В противном случае, сообщение об ошибке будет содержать разницу между словарями. Этот метод будет использован по умолчанию для сравнения словарей при вызове assertEqual().
New in version 2.7.
Наконец, TestCase предоставляет следующие методы и атрибуты:
fail(msg=None) Сигнализирует о безусловном «падении» теста; в качестве сообщения об ошибке будет выведено msg или None. failureException Этот атрибут содержит исключение, вызываемое тестом. Если тестовый фреймворк должен использовать специализированные исключения, возможно, содержащие дополнительную информацию, то оно должно быть подклассом этого исключения, для того, чтобы «честно» играть с фреймворком. Значение по умолчанию — AssertionError. longMessage Если установлено в True, тогда все явные сообщения об ошибках, передаваемые в методы исключение будут добавлены к концу стандартного сообщения об ошибке. Стандартное сообщение об ошибке содержит полезную информацию об используемых объектах, например, сообщение от assertEqual покажет вам представление (repr) двух не равных объектов. Установка этого атрибута в True позволит Вам кроме этого сообщения добавить и какое-то своё.
По умолчанию этот атрибут равен False, что означает, что пользовательское сообщение, переданное методу исключения, затрёт стандартное сообщение.
Настройки класса могут быть переопределены в индивидуальных тестах, присваивая атрибуту экземпляра True или False перед вызовом методов исключения.
New in version 2.7. maxDiff Этот атрибут определяет максимальную длину разницы, выводимой методами исключения при не прохождении теста. По умолчанию он равен 80*8 символов. Методы исключения, на которые влияет этот атрибут — это assertSequenceEqual() (включая все последующие методы сравнения, которым метод делегирует свою работу), assertDictEqual() и assertMultiLineEqual().
Установка maxDiff в None означает, что нет ограничения по длине.
New in version 2.7.
Фреймворки для тестирования могут использовать следующие методы для сбора информации о тесте:
countTestCases() Возвращает количество тестов, представленных этим тестовым объектом. Для экземпляров TestCase, это всегда будет 1. defaultTestResult() Возвращает экземпляр класса результата теста, который должен быть исопльзован для этого тестового случая (если других экземпляров результатов не предоставлено методу run()).
Для экземпляров TestCase он всегда будет экземпляром класса TestResult; подклассы TestCase должны переопределять его по необходимости. id() Возвращает строку, идентифицирующую определённый тестовый случай. Обычно это полное имя тестового метода, включающее в себя имена модуля и класса. shortDescription() Возвращает описание теста или None, если описания нет. Реализация этого метода по умолчанию возвращает первую строку из строк документации для метода, если она есть, или None. addCleanup(function, *args, **kwargs) Добавляет функцию, которая должна быть вызвана после tearDown() для уборки ресурсов, использованных в процессе тестирования. Функции будут вызываться в обратном порядке от их добавления (LIFO). Они вызываются с позиционными и именованными аргументами, переданными в addCleanup().
Если setUp() не срабатывает, то есть и tearDown() не вызывается, то все добавленные при помощи этого метода функции всё равно будут вызываны.
New in version 2.7. doCleanups() Этот мтеод вызывается в любом случае после tearDown(), или setUp(), если setUp() вызывал исключение.
Он отвечает за вызов всех отчищающих функций, добавленных методом addCleanup(). Если Вам нужно вызывать какие-то функции до tearDown(), тогда Вы должны вызвать метод doCleanups() сами.
doCleanups() вытаскивает (pop) методы из стека отчищающих функций по одной, так что она может быть вызвана в любое время.
New in version 2.7. class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None) Этот класс реализует часть интерфейса TestCase, который позволяет исполнителю тестов провести тест, но не предоставляет методов, которые тестовый код может использовать для проверки и сообщении об ошибках. Он используется для создания тестовых случаев при помощи «наследственного» тестового кода, позволяя интегрировать его в основанные на unittest тестирующие фреймворки.
Устаревшие псевдонимыПо историческим причинам, некоторые методы класса TestCase имеют один или более псевдонимов, которые на данный момент уже устарели. Следующая таблица перечисляет корректные имена вместе с их устаревшими псевдонимами:
Имя метода Устаревшие псевдонимы assertEqual() failUnlessEqual, assertEquals assertNotEqual() failIfEqual assertTrue() failUnless, assert_ assertFalse() failIf assertRaises() failUnlessRaises assertAlmostEqual() failUnlessAlmostEqual assertNotAlmostEqual() failIfAlmostEqualDeprecated since version 2.7: псевдонимы, перечисленные во втором столбце
Группировка тестовЕсли передан аргумент 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__(). Обратите внимание, что этот метод может быть вызван несколько раз для одного набора (например, когда подсчитывается количество тестов или они сравниваются на идентичность), так что тесты, возвращаемые методом, должны быть одинаковы для все повторных итераций.
Changed in version 2.7: В ранних версиях TestSuite к тестам обращались на прямую, а не через итерации, так что переопределение __iter__() не было достаточным для доступа к тестам.
При типичном использовании объекта TestSuite, метод run() вызывается классом TestRunner, а не конечным пользователем теста.
Загрузка и выполнение тестовОбъекты TestLoader имеют следующие методы:
loadTestsFromTestCase(testCaseClass) Возвращает набор из всех тестов, содержащихся в testCaseClass, полученном из TestCase. loadTestsFromModule(module) Возвращает набор из всех тестов, содержащихся в полученном модуле. Этот метод просматривает module в поисков классов, унаследованных от TestCase и создаёт экземпляр класса для каждого метода, определённого в классе.
Хотя использование иерархии из наследников класса TestCase может быть нормой в общих «стендах» и вспомогательных функциях, определение тестовых методов на базе классов, которые не предназначены для прямого вызова не будет нормально работать с этим методом. Но это может быть полезным в случае других «стендов», которые определены в подклассах.
Если модуль предоставляет функцию load_tests, то она будет вызвана для загрузки тестов. Это позволяет модулям настроить загрузку тестов. Это `load_tests protocol`_ .
Changed in version 2.7: Добавлена поддержка load_tests. loadTestsFromName(name, module=None) Возвращает набор из всех тестов для объекта, определённого строкой.
Определитель name является именем в точечной нотации, которое может быть разрешено в модуль, класс тестового случая, тестовый метод в классе теста, экземпляр TestSuite или в вызываемый объект, который возвращает экземпляры TestCase или TestSuite. Эти проверки применяются в указанном тут порядке. То есть метод в возможном классе тестового случая будет рассматриваться как «тестовый метод в классе тестового случая», а не как «вызываемый объект».
Например, если у Вас есть модуль SampleTests, содержащий класс SampleTestCase, унаследованный от TestCase с тремя тестовыми методами (test_one(), test_two(), и test_three()), то определитель ‘SampleTests.SampleTestCase’, переданный этому методу вернёт набор, который будет запускать все эти три метода. Использование определителя ‘SampleTests.SampleTestCase.test_two’ вернёт набор тестов, в котором будет содержаться только один тест — метод test_two(). Определитель может ссылаться на модули и пакеты, которые не были импортированы; как «побочный эффект» они будут импортированы.
Этот метод опционально расширяет name относительно данного module. loadTestsFromNames(names, module=None) Похож на loadTestsFromName(), но принимает последовательность имён, а не одно имя. Возвращает набор тестов, который поддерживает все тесты,
определённые для каждого имени. getTestCaseNames(testCaseClass) Возвращает отсортированную последовательность имён методов, найденных в testCaseClass, который должен быть подкласс от TestCase. discover(start_dir, pattern=’test*.py’, top_level_dir=None) Обнаруживает и возвращает все тестовые модули из определённого стартового каталога, проходясь и по всем подкаталогам. Будут загружены только те тестовые файлы, которые соответствуют pattern. (Используется соотвествие шаблону в стиле shell.) Будут загружены только те имена модулей, которые можно импортировать (то есть, которые являются корректными идентификаторами Python).
Все тестовые модули должны быть импортируемы с верхнего уровня проекта. Если стартовый каталог не является каталогом верхнего уровня, тогда каталог верхнего уровня должен быть указан отдельно.
Если импорт модуля не удаётся, например, из-за синтаксической ошибки, тогда это будет записано как отдельная ошибка и поиск тестов будет продолжен.
Если имя тестового пакета (каталога с файлом __init__.py) соответсвует шаблону, тогда пакет будет проверен на наличие функции load_tests. Если эта функция существует, то она будет вызвана с аргументами loader, tests, pattern.
Если существует load_tests, тогда поиск тестов не проводит рекурсию по пакету, load_tests сама отвечает за загрузку всех тестов пакета.
Шаблон намеренно не хранится как атрибут загрузчика, так что пакеты могут искать тесты сами. top_level_dir хранится, так что load_tests не нуждается в передаче этого аргумента в loader.discover().
start_dir может быть точечным именем модуля или каталогом.
New in version 2.7.
Следующие атрибуты TestLoader могут быть настроены либо при помощи создания подкласса, либо настройкой экземпляра:
testMethodPrefix Строка с префиксом имён методов, которые будут интерпретированны как тестовые методы. Значение по умолчанию — ‘test’.
Это влияет на getTestCaseNames() и все методы loadTestsFrom*(). sortTestMethodsUsing Функция, которая будет использована для сравнения имён методов во время сортировки в getTestCaseNames() и всех методах loadTestsFrom*(). Значение по умолчанию — встроенная функция cmp(); атрибуту может быть присвоено значение None, чтобы отменить сортировку. suiteClass Вызываемый объект, который создаёт набор тестов из списка тестов. Для итогового объекта не надо создавать никаких дополнительных методов (No methods on the resulting object are needed). Значение по умолчанию — класс TestSuite.
Влияет на все методы loadTestsFrom*(). class unittest.TestResult Этот класс используется для компиляции информации о том, какие тесты прошли успешно, а какие — нет.
Объекты TestResult хранят результаты набора тестов. Классы TestCase и TestSuite следят за тем, чтобы результаты тестов были корректно записаны; авторы тестов не должны заботиться о сохранении их результатов.
Тестирующие фреймворки, построенные на основе unittest могут хотеть получить доступ к объекту TestResult, сгенерированному при запуске набора тестов для изменения вывода результатов; для этих целей метод TestRunner.run() возвращает экземпляр TestResult.
Экземпляры TestResult имеют следующие атрибуты, которые могут быть интересны при исследовании результатов выполнения набора тестов:
errors Список, содержащий кортежи из 2-х элементов: экзмепляра TestCase и строки, содержащей отформатированную трассировку. Каждый кортеж представляет собой тест, который вызвал неожиданное исключение.
Changed in version 2.2: Содержит отформатированную трассировку, а не результат функции sys.exc_info(). failures Список, содержащий кортежи из 2-х элементов: экзмепляра TestCase и строки, содержащей отформатированную трассировку. Каждый кортеж представляет собой тест, в котором произошла ошибка, вызванная методами TestCase.assert*().
Changed in version 2.2: Содержит отформатированную трассировку, а не результат функции sys.exc_info(). skipped Список, содержащий кортежи из 2-х элементов: экзмепляра TestCase и строки, описывающей причину пропуска теста.
New in version 2.7. expectedFailures Список, содержащий кортежи из 2-х элементов: экзмепляра TestCase и строки, содержащей отформатированную трассировку. Каждый кортеж представляет собой ожидаемую ошибку теста. unexpectedSuccesses Список, содержащий экзмепляры TestCase, которые были помечены как ожидающие ошибки, но ошибки не произошло. shouldStop Установлено в True, если выполение теста должно быть остановлено методом stop(). testsRun Общее количество выполненных на данный момент тестов. buffer Если установлен в true, то sys.stdout и sys.stderr будут буфферизованы между вызовами startTest() и stopTest(). Собранный вывод будет отправлен в реальный sys.stdout и sys.stderr если тест выдаст ошибку или неудачу. Любой вывод будет также добавлен к сообщению об ошибке/неудаче.
New in version 2.7. failfast Если установлен в true, stop() будет вызван для первой же ошибки / неудаче и выполнение тестов будет остановлено.
New in version 2.7. wasSuccessful() Возвращает True, если все тесты до сих пор были пройдены, в противном случае возвращает False. stop() Этот метод может быть вызван для того, чтобы сообщить о том, что выполнение текущего набора тестов должно быть прервано. Это достигается заданием значения True для атрибута shouldStop. Объекты TestRunner должны учитывать этот флаг и прекращать своё выполнение без запуска дополнительных тестов.
Например, эта возможность используется классом TextTestRunner для того, чтобы остановить выполнение тестов, когда пользователь прерывает выполнение тестов с клавиатуры. Интерактивные инструменты, предоставляющие реализацию TestRunner могут использовать этот метод схожим образом.
Следующие методы класса TestResult используются для обслуживания внутренних структур данных и может быть расширен в подклассах для поддержки дополнительных возможностей вывода информации. Это особенно полезно при создании инструментов, которые поддерживают интерактивное оповещение о результатах в процессе выполнения тестов.
startTest(test) Вызывается, перед тем, как тестовый случай test будет запущен. stopTest(test) Вызывается после того, как тестовый случай test был выполнен, вне зависимости от результата. startTestRun(test) Вызывается один раз перед запуском любого теста (видимо, перед началом выполнения всех тестов).
New in version 2.7. stopTestRun(test) Вызывается после выполнения всех тестов.
New in version 2.7. 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 экземпляра. class unittest.TextTestResult(stream, descriptions, verbosity) Конкретная реализация TestResult, используемая классом TextTestRunner.
New in version 2.7: Этот класс раньше назывался _TextTestResult. Старое имя всё ещё существует как псевдоним, но не рекомендуется. unittest.defaultTestLoader Экземпляр класса TestLoader, который должен быть общим (intended to be shared). Если не требуется дополнительной настройки TestLoader, то этот экземпляр может быть использован несколько раз, вместо того, чтобы создавать новые экзмепляры. class unittest.TextTestRunner(stream=sys.stderr, descriptions=True, verbosity=1) Базовая реализация выполнителя тестов, которая выводит результаты на стандартный вывод ошибок. У неё всего несколько настраеваемых параметров, но она очень проста. Графиеские приложения, котоыре запускают тесты, должны предоставить альтернативную реализацию.
_makeResult() Этот метод возвращает экземпляр TestResult, используемый методом run(). Он не предназначен для непосредственного вызова, но может быть переопределён в подклассах для предоставления собственного TestResult.
_makeResult() создаёт экземпляр из класса или вызываемого объекта, переданного в конструктор TextTestRunner как аргумент resultclass. По умолчанию это TextTestResult. Экзмепляр будет создан со следующими аргументами: