unittest
— Фреймворк тестирования юнитов¶
New in version 2.1.
(Если вы уже знакомы с основами концепции тестирования, то вы, возможно, захотите перейти сразу к список методов утверждений (assert methods).)
Фреймворк тестирования юнитов Python, иногда называемый “PyUnit”, является версией Python`а для JUnit от Kent Beck и Erich Gamma. JUnit, в свою очередь, является Java версией фреймворка тестирования от Kent’а для Smalltalk. Каждый из них является стандартом де факто для своего языка.
unittest
поддерживает автоматизацию тестов, использование общего кода
для настройки и завершения тестов, объединение тестов в коллекции и
отделение тестов от фреймворка для вывода информации. Модуль 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
как пример
выполнителя тестов, который по умолчанию выводит итог в стандартный поток
ошибок. Альтернативные выполнители тестов могут быть реализованы и для
других окружений (например, графических) без необходимости наследования из
определённого класса.
See also
- Module
doctest
- Другой модуль тестирования с совершенно другим подходом.
unittest2: Обратное портирование новых возможностей unittest для Python 2.4-2.6
В unittest для Python 2.7 было добавлено много новых возможностей, включая поиск тестов. unittest2 позволяет использовать эти возможности в более ранних версиях Python.
- Simple Smalltalk Testing: With Patterns
- статья Kent Beck’а про фреймворк для тестирования, использующий общий
с
unittest
шаблон. - Nose и py.test
- сторонний фреймворк тестирования, использующий лёгкий синтаксис для
написания тестов. Например,
assert func(10) == 42
. - The Python Testing Tools Taxonomy
- Расширяемый список инструментов для тестирования на Python, включая фреймворки для функционального тестирования и библиотеки mock-объектов.
- Testing in Python Mailing List
- Группа по интересам для обсуждения тестирования и инструментов для этого в Python.
Основные примеры¶
Модуль unittest
предоставляет бокатый набор инструментов для создания
и запуска тестов. Этот раздел демонстрирует, что небольшой набор этих
инструментов удволетвоярет большинство ваших потребностей.
Вот короткий скрипт для тестирования трёх функций из модуля random
:
import random
import unittest
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def test_shuffle(self):
# проверяем, что перемешанная последовательность не потеряла
# ни одного элемента
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, range(10))
# возбуждает исключение для неизменяемых последовательностей
self.assertRaises(TypeError, random.shuffle, (1,2,3))
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
if __name__ == '__main__':
unittest.main()
Набор тестов создаётся при помощи подкласса unittest.TestCase
. Три
отдельных теста определены в методах, чьи имена начинаются с test
. Это
соглашение об именах сообщает выполнителю тестов о том, какие методы
содержат тесты.
Задачей каждого теста является вызов assertEqual()
для
проверки ожидаемого вывода; assertTrue()
для проверки
условий; или assertRaises()
для проверки того, что)
возбуждается ожидаемое исключение. Эти методы используются вместо выражения
assert
, так что выполнитель тестов может собирать все результаты
тестов и создавать отчёт.
Когда определён метод setUp()
, выполнитель тестов запустит
этот метод перед каждым тестом. Похожим образом если определён метод
tearDown()
, выполнитель тестов будет вызывать этот метод
после каждого теста. В нашем примере setUp()
использовался
для создания свежей последовательности для каждого теста.
Финальный блок показывает простой способ выполнить тесты.
unittest.main()
предоставляет интерфейс командной строки к тестовому
скрипту. Когда он запускается из командной строки, скрипт из примера выше
даст вывод вроде этого:
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
Вместо unittest.main()
, есть другие способы запуска тестов с более
точным управлением, более подробным выводом, и для которых не обязательно
использовать командную строку. Например, последние две строки можно заменить
следующими детальным
управление:
suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
unittest.TextTestRunner(verbosity=2).run(suite)
Запустив полученный скрипт в интерпретаторе или в другом скрипте, мы получим следующий вывод:
test_choice (__main__.TestSequenceFunctions) ... ok
test_sample (__main__.TestSequenceFunctions) ... ok
test_shuffle (__main__.TestSequenceFunctions) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.110s
OK
Примеры выше показывают наиболее стандартный способ использования
возможностей unittest
, которые позволяют удовлетворить ваши
повседневные потребности. Остальная часть документации описывает полный
набор всех возможностей.
Интерфейс командной строки¶
Модуль unittest может быть использован из командной строки для запуска тестов из модулей, классов или даже отдельных методов:
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method
Вы можете использовать список с любой комбинацией имён модулей и полных имён классов или методов.
Вы можете запускать тесты в более детальном режиме при помощи флага -v:
python -m unittest -v test_module
Для получения полного списка всех опций командной строки:
python -m unittest -h
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()
, но может быть
использован и из командной строки. Пример использования:
cd project_directory
python -m unittest 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
, вместо начального каталога. Имя пакета,
которое вы указываете будет импортировано, а его расположение в файловой
системе будет использовано как начальный каталог.
Caution
Обнаружение теста загружает тесты импортируя их. После того, как были
найдены все тестовые файлы в стартовом каталоге, их пути преобразуются
в имена пакетов для импорта. Например, foo/bar/baz.py
будет
импортирован как foo.bar.baz
.
Если у вас есть глобально установленный пакет и вы пытаетесь обнаружить тесты в другой копии пакета, тогда импорт возможно произойдёт из неверного места. Если это происходит, обнаружитель тестов предупредит вас об этом и завершит работу.
Если вы указываете в качестве стартового каталога имя пакета, а не путь к каталогу, тогда обнаружитель подразумевает, что откуда бы не импортировался пакет, он импортируется из верного места, так что вы не получите предупреждения.
Модули и пакеты тестов могут настроить загрузку и поиск тестов при помощи `протокола load_tests`_.
Организация тестового кода¶
Основные строительные блоки юнит-тестов — тестовый случай — одиночные
сценарии, которые должны быть настроены и проверены на корректное
выполнение. В unittest
, тестовые случаи представлены экземплярами
класса TestCase
unittest
‘а. Для того, чтобы сделать свой
тестовый случай вы должны написать подкласс TestCase
, или
использовать FunctionTestCase
.
Экземпляр класса-наследника от TestCase
является объектом, который
может запустить один тестовый метод вместе с опциональным кодом настройи
и очистки.
Тестовый код экземпляра TestCase
должен быть полностью
самодостаточным, так что его можно запускать в изоляции или в
произвольной комбинации с любым другим количеством тестовых случаев.
Простейший подкласс TestCase
просто переопределяет метод
runTest()
для того, чтобы выполнять конкретный код теста:
import unittest
class DefaultWidgetSizeTestCase(unittest.TestCase):
def runTest(self):
widget = Widget('The widget')
self.assertEqual(widget.size(), (50, 50), 'incorrect default size')
Обратите внимание, что для того, чтобы протестировать что-то мы используем
один из assert*()
методов, предоставляемых базовым классом
TestCase
. Если тест не удаётся, будет возбуждено исключение, и
unittest
пометит этот тестовый случай как failure. Все другие
исключения будут трактоваться как errors. Это поможет вам определить,
в чём кроется проблема: failures возникает при некорректом результате
- вы ожидали 6, а получили 5. Errors возникают из-за ошибок в коде,
например, TypeError
при некорректном вызове функции.
Способ запуска тестового случая будет описан ниже. На данный момент, обратите внимание, что для создания экземпляра такого тестового случая, мы вызываем конструктор без аргументов:
testCase = DefaultWidgetSizeTestCase()
Далее, таких тестовых случаем может быть несколько, а их настройка может
быть одинаковой. В таком случае, создание Widget
в каждом из 100
тестовых случаев для подклассов может означать ненужное дублирование.
К счастью, мы можем вынести настроечный код, реализовав метод
setUp()
, который автоматически вызывается фреймворком, когда
мы запускаем тест:
import unittest
class SimpleWidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):
def runTest(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
class WidgetResizeTestCase(SimpleWidgetTestCase):
def runTest(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
Если метод setUp()
возбуждает исключение во время выполнения
теста, фреймворк предполагает, что тест содержит существенную ошибку и
метод runTest()
даже не будет запущен.
Похожим образом, мы можем предоставить метод tearDown()
,
который выполняется после метода runTest()
:
import unittest
class SimpleWidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
self.widget = None
Если setUp()
выполняется успешно, метод
tearDown()
будет выполнен вне зависимости от метода
runTest()
.
Такое рабочее окружение для тестирования называется стендом.
Достаточно часто несколько маленьких тестов используют один и тот же стенд.
В этом случае мы приходим к созданию большого числа маленьких однометодовых
подклассов SimpleWidgetTestCase
, таких как
DefaultWidgetSizeTestCase
. Это требует уйму времени и утомительно,
так что в том же духе, что и JUnit, unittest
предоставляет похожий
механизм:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
self.widget = None
def test_default_size(self):
self.assertEqual(self.widget.size(), (50,50),
'incorrect default size')
def test_resize(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(), (100,150),
'wrong size after resize')
Тут мы не использовали метод runTest()
, а вместо него
релизовали два других тестовых метода. Экмзепляр класса теперь запустит
каждый из test_*()
методов, где self.widget
будет создан и
разрушен отдельно для каждого экземпляра. Когда мы создаём экземпляр, мы
должны определить тестовый метод, который он будет выполнять. Мы делаем это
передвая имя метода в конструктор:
defaultSizeTestCase = WidgetTestCase('test_default_size')
resizeTestCase = WidgetTestCase('test_resize')
Экземпляры тестового случая группируются вместе в соответствии с
функционалом, который они тестирюут. unittest
предоставляет для этого
механизм: набор тестов, предоставленный классом TestSuite
unittest
‘а:
widgetTestSuite = unittest.TestSuite()
widgetTestSuite.addTest(WidgetTestCase('test_default_size'))
widgetTestSuite.addTest(WidgetTestCase('test_resize'))
Для того, чтобы проще запускать тесты, как мы увидим позже, хорошей идеей будет предоставить в каждом тестовом модуле вызываемый объект, который возвращает уже готовый набор тестов:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_size'))
suite.addTest(WidgetTestCase('test_resize'))
return suite
или даже:
def suite():
tests = ['test_default_size', 'test_resize']
return unittest.TestSuite(map(WidgetTestCase, tests))
Так как создание подкласса TestCase
с многими похоже названными
функциями широко распространено, unittest
предоставляет класс
TestLoader
, который может быть использован для создания набора
тестов и наполнения его тестами. Например:
suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)
создаст набор тестов, который выполнит
WidgetTestCase.test_default_size()
и WidgetTestCase.test_resize
.
TestLoader
использует префикс имени метода 'test'
для
идентификации тестовых методов.
Обратите внимание, что порядок, в котором тесты будут запущены определяется сортировкой имён тестовых функций согласно встроенному порядку сортировки строк.
Часто бывает желательно сгруппировать наборы тестов, чтобы запускать тесты
для всей системы одновременно. Это легко сделать, так как экземпляры
TestSuite
могут быть добавлены в TestSuite
, как и
экземпляры TestCase
:
suite1 = module1.TheTestSuite()
suite2 = module2.TheTestSuite()
alltests = unittest.TestSuite([suite1, suite2])
Вы можете расположить определения тестовых случаев и наборов тестов в том же
модуле, что и код, который они тестируют (например, в файл
widget.py
), но есть преимущества в расположении теста в отдельном
модуле, например в test_widget.py
:
- Тестовый модуль может быть запущен отдельно из командной строки.
- Тестовый код легче отделить от поставляемого кода.
- Гораздо меньше соблазна изменить тестовый код, чтобы он соответствовал тестируемому коду без весомой причины.
- Тестовый код должен меняться гораздо реже, чем тестируемый.
- Тестовый код можно проще подвергнуть рефакторингу.
- Тесты для модулей, написаных на С, должны быть отделены от модулей, так почему бы не сделать так со всеми тестами?
- Если стратегия тестирования изменяется, то нет нужды менять исходный код.
Повторное использование тестового кода¶
Некоторые пользователи могут обнаружить, что у них уже есть тестовый
код, который они хотели бы запустить из под unittest
, без того, чтобы
преобразовывать все тестовые функции в подклассы TestCase
.
По этой причине unittest
предоставляет класс
FunctionTestCase
. Этот подкласс класса TestCase
может быть
использован как обёртка для существующих тестовых функций. Так же для него
есть функции настройки и очистки.
Предположим, у нас есть следующая тестовая функция:
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
для которой можно создать эквивалентный экземпляр тестового случая:
testcase = unittest.FunctionTestCase(testSomething)
Если есть дополнительные методы настройки и очистки, которые должны быть вызваны как часть теста, то их тоже можно указать:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
Для того, чтобы облегчить миграцию существующих тестовых наборов,
unittest
позволяет тестам возбуждать AssertionError
для
обозначения падения теста. Однако, рекомендуется вместо этого
явно использовать методы TestCase.fail*()
и TestCase.assert*()
,
так как будущие версии unittest
могут трактовать AssertionError
по другому.
Note
Хотя FunctionTestCase
может быть использован для быстрой
конвертации существующих тестов в систему, основанную на unittest
,
делать так не рекомендуется. Затраченное время на создание
соответствующего подкласса TestCase
позволит вам позже проще
проводить рефакторинг теста.
В некоторых случаях существующие тесты могут быть написаны при помощи модуля
doctest
. Этот модуль предоставляет класс DocTestSuite
,
который может автоматически создать экземпляр класса
unittest.TestSuite
из существующих тестов, основанных на
doctest
.
Игнорирование тестов и ожидаемые ошибки¶
New in version 2.7.
Unittest поддерживает игнорирование отдельных тестовых методов и даже целых
тестовых классов. Кроме того, он поддерживает возможность пометить тест как
“ожидающий ошибку”, что означает, что тест сломан и не будет пройден, но не
должен учитываться как не пройденный экземпляром TestResult
.
Пропуск теста делается просто использованием skip()
decorator
или одного из его условных вариантов.
Игнорирование в простом случае выглядит так:
class MyTestCase(unittest.TestCase):
@unittest.skip("демонстрируем игнорирование")
def test_nothing(self):
self.fail("не произойдёт")
@unittest.skipIf(mylib.__version__ < (1, 3),
"не поддерживается этой версией библиотеки")
def test_format(self):
# Тестирование работы только для определённой версии библиотеки.
pass
@unittest.skipUnless(sys.platform.startswith("win"),
"требуется Windows")
def test_windows_support(self):
# код тестирования под windows
pass
Вот вывод этих примеров в “говорливом” режиме:
test_format (__main__.MyTestCase) ... skipped 'не поддерживается этой версией библиотеки'
test_nothing (__main__.MyTestCase) ... skipped 'демонстрируем игнорирование'
test_windows_support (__main__.MyTestCase) ... skipped 'требуется Windows'
----------------------------------------------------------------------
Ran 3 tests in 0.005s
OK (skipped=3)
Классы можно пропускать так же как и методы:
@unittest.skip("показываем пропуск классов")
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)[source]¶ Безусловно пропускает декорированный тест. reason должен описывать причину, почему тест был пропущен.
-
unittest.
skipUnless
(condition, reason)[source]¶ Пропускает декорированный тест, пока condition не будет истинным.
-
unittest.
expectedFailure
()[source]¶ Помечает тест, как ожидающий ошибку. Если тест не проходит, он не засчитывается как ошибка в результатах.
-
exception
unittest.
SkipTest
(reason)[source]¶ Это исключение вызывается для пропуска теста.
Обычно вы можете использовать
TestCase.skipTest()
или один из декораторов вместо непосредственного вызова исключения.
Пропущенный тест не будет выполнять методы setUp()
или
tearDown()
. Пропущенные классы не будут выполнять методы
setUpClass()
или tearDownClass()
.
Классы и функции¶
Этот раздел подробно описывает API модуля unittest
.
Test cases¶
-
class
unittest.
TestCase
(methodName='runTest')[source]¶ Экземпляры класса
TestCase
представляют небольшие тестируемые кусочки из “вселенной”unittest
. Этот класс должен быть использован как базовый класс, где конкретные тесты реализуются конкретными подклассами. Этот класс реализует интерфейсы, необходимые выполнителю тестов для выполнения тестов и методы, которые тестовый код может использовать для проверки и оповещения о различных ошибках.Каждый экземпляр
TestCase
будет запускать один тестовый метод: метод и именем methodName. Если вы помните, у нас уже был пример чего-то вроде этого:def suite(): suite = unittest.TestSuite() suite.addTest(WidgetTestCase('test_default_size')) suite.addTest(WidgetTestCase('test_resize')) return suite
Тут мы создаём два экземпляра класса
WidgetTestCase
, каждый из которых запускает один тест.methodName по умолчанию является
runTest()
.Экземпляры
TestCase
предоставляют три группы методов: одна группа используется для запуска тестов, другая используется реализацией теста для проверки условий и сообщейний об ошибках, а некоторые методы позволяют собирать информацию о самих тесатх.Методы в первой группе (запуск тестов):
-
setUp
()[source]¶ Метод вызывается для подготовки тестового стенда. Он вызывается непосредственно перед вызовом тестового метода; все исключения вызываемыми этим методом будут трактоваться как ошибки, а не как провал теста. По умолчанию ничего не делает.
-
tearDown
()[source]¶ Метод вызывается сразу после вызова тестового метода и сохранения результата. Он вызывается даже если тестовый метод вызвал исключение, так что его реализация в подклассе должна особенно внимательно относиться к проверке внутреннего состояния. Все исключения, вызванные этим методом будут трактоваться как ошибки, а не как провал теста. Этот метод вызывается только если
setUp()
завершился успешно, вне зависимости от результата тестового метода. Реализация по умолчанию не делает ничего.
-
setUpClass
()[source]¶ Метод класса выызваемый перед запуском тестов в классе.
setUpClass
вызывается только с одним аргументом - классом, и должен быть декорированным при помощиclassmethod()
:@classmethod def setUpClass(cls): ...
Более подробно смотрите в Стенды класса и модуля .
New in version 2.7.
-
tearDownClass
()[source]¶ Метод класса, вызываемый после тестов в классе.
tearDownClass
вызывается только с одним аргументом - классом, и должен быть декорирован при помощиclassmethod()
:@classmethod def tearDownClass(cls): ...
Более подробно смотрите в Стенды класса и модуля .
New in version 2.7.
-
run
(result=None)[source]¶ Запускает тест, собирает резльутат в объект результата теста, полученный через result. Если result не указан или равен
None
, создаётся временный объект результата (при помощи вызова методаdefaultTestResult()
), который затем и используется. Объект результата не возвращается вызвашемуrun()
.Тот же самый эффект может быть достигнут простым вызовом экземпляра
TestCase
.
-
skipTest
(reason)[source]¶ Вызов этого метода в тестовом методе или в
setUp()
приведёт к пропуску теста. Более подробно смотрите в Игнорирование тестов и ожидаемые ошибки.New in version 2.7.
-
debug
()[source]¶ Запуск теста без сбора результата. Это позволяет исключениям, которые вызываются тестом быть переданными вызывающему объекту и его можно использовать для поддержки запуска теста в режиме отладки.
Класс
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)[source]¶ Проверяет, что first и second равны. Елси они не равны - тест не пройден.
Кроме того, если first и second одного и того же типа и принадлежат list, tuple, dict, set, frozenset, unicode или любому другому типу, который является подклассом, зарегистрированным при помощи
addTypeEqualityFunc()
, будет вызвана специфичная для этого типа функция сравнения для того, чтобы получить более детальное сообщение об ошибке (смотрите также список методов специфичных для типов).Changed in version 2.7: Добавлен автоматический вызов функций сравнения, специфичных для определённого типа.
-
assertNotEqual
(first, second, msg=None)[source]¶ Проверяет, что first и second не равны. Если значения равны, то тест считается проваленным.
-
assertTrue
(expr, msg=None)[source]¶ -
assertFalse
(expr, msg=None)[source]¶ Проверяет, что expr истинно (или ложно).
Обратите внимание, что это эквивалентно
bool(expr) is True
а неexpr is True
(для второго варианта используйтеassertIs(expr, True)
). Этот метод также не стоит использовать когда есть более конкретные методы (например,assertEqual(a, b)
вместоassertTrue(a == b)
), так как они обеспечивают лучшие сообщения об ошибках.
-
assertIs
(first, second, msg=None)[source]¶ -
assertIsNot
(first, second, msg=None)[source]¶ Проверяет, что first и second вычисляются (или не вычисляются) в тот же самый объект.
New in version 2.7.
-
assertIsNone
(expr, msg=None)[source]¶ -
assertIsNotNone
(expr, msg=None)[source]¶ Проверяет, что expr является (или нет) None.
New in version 2.7.
-
assertIn
(first, second, msg=None)[source]¶ -
assertNotIn
(first, second, msg=None)[source]¶ Проверяет, что first (не) находится в second.
New in version 2.7.
-
assertIsInstance
(obj, cls, msg=None)[source]¶ -
assertNotIsInstance
(obj, cls, msg=None)[source]¶ Проверяет, что obj (не) является экземпляром класса cls (который может быть классом или кортежем классов, как это поддерживается функцией
isinstance()
). Для того, чтобы проверить точное соответствие типу используйтеassertIs(type(obj), cls)
.New in version 2.7.
Кроме того, можно проверить, какое исключение или предупреждение было выдано при помощи следующих методов:
Метод Проверяет что Начиная с assertRaises(exc, fun, *args, **kwds)
fun(*args, **kwds)
вызывает excassertRaisesRegexp(exc, r, fun, *args, **kwds)
fun(*args, **kwds)
вызывает exc и сообщение соответствует regex r2.7 -
assertRaises
(exception, callable, *args, **kwds)[source]¶ -
assertRaises
(exception) Проверяет, что при вызове callable с переданными позиционными или именованными аргументами вызовет исключение. Тест считается пройденным, если вызывается исключение exception, ошибкой будет считаться вызов другого исключения, а провалом теста - если исключение не вызвано. Для того, чтобы перехватить группу исключений, можно передать в качестве exception кортеж, который содержит эти исключения.
Если передан только аргумент exception, возвращается менеджер контекста, так что код для тестирования можно записать прямо в строку, вместо того, чтобы его оформлять в виде функции:
with self.assertRaises(SomeException): do_something()
Менеджер контекста сохраняет объект перехваченного исключения в своём атрибуте
exception
. Это может быть полезным, если мы хотим провести дополнительные проверки возбуждённого исключения:with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3)
Changed in version 2.7: Добавлена возможность использовать
assertRaises()
как менеджер контекста.
-
assertRaisesRegexp
(exception, regexp, callable, *args, **kwds)¶ -
assertRaisesRegexp
(exception, regexp) Похож на
assertRaises()
, но кроме этого проверяет, что regexp соответствует строковому представлению вызванного исключения. regexp может быть объектом регулярного выражения или строкой, содержащей регулярное выражение, которое можно использовать вre.search()
. Например:self.assertRaisesRegexp(ValueError, "invalid literal for.*XYZ'$", int, 'XYZ')
или:
with self.assertRaisesRegexp(ValueError, 'literal'): int('XYZ')
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)[source]¶ -
assertNotAlmostEqual
(first, second, places=7, msg=None, delta=None)[source]¶ Проверяет, что 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)[source]¶ -
assertGreaterEqual
(first, second, msg=None)[source]¶ -
assertLess
(first, second, msg=None)[source]¶ -
assertLessEqual
(first, second, msg=None)[source]¶ Проверяет, что first соответственно >, >=, < или <= чем second, в зависимости от имени метода. Если нет, то тест не проходит:
>>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4"
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)[source]¶ Проверяет, что пары key/value в словаре actual являются надмножеством тех, что есть в expected. Иначе будет выведено сообщение об ошибке, содержащее отсутствующие ключи и не соответствующие значения.
New in version 2.7.
Deprecated since version 3.2.
Метод
assertEqual()
передаёт проверку равенства объектов одного типа различным типо-специфическим методам. Этим методы уже реализованы для для большей части встроенных типов, но можно зарегистрировать и свои методы при помощиaddTypeEqualityFunc()
:-
addTypeEqualityFunc
(typeobj, function)[source]¶ Регистрирует специфичный для типа метод, вызываемый
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)[source]¶ Проверяет, что многострочная строка first равна строке second. Если они не равны, то разница между двумя строками будет включена в сообщение об ошибке. Этот метод используется по умолчанию при сравнении строк при помощи
assertEqual()
.New in version 2.7.
-
assertSequenceEqual
(seq1, seq2, msg=None, seq_type=None)[source]¶ Проверяет, что две последовательности равны. Если указан seq_type, то и seq1 и seq2 должны быть экземплярами seq_type или будет возбуждено исключение. Если последовательности отличаются, то будет выведено сообщение об ошибке, содержащее разницу между двумя последовательностями.
Этот метод не вызывается напрямую методом
assertEqual()
, но он используется для реализацииassertListEqual()
иassertTupleEqual()
.New in version 2.7.
-
assertListEqual
(list1, list2, msg=None)[source]¶ -
assertTupleEqual
(tuple1, tuple2, msg=None)[source]¶ Проверяет, что два списка или корежа равны. В противном случае будет выдано сообщение об ошибке, содержащее разницу между двумя последовательностями. Ошибка так же появится в случае, если какой-либо параметр не того типа. Эти методы по умолчанию используются для сравнения списков и кортежей методом
assertEqual()
.New in version 2.7.
-
assertSetEqual
(set1, set2, msg=None)[source]¶ Проверяет, что два множества равны. Иначе будет показано сообщение об ошибке, которое содержит разницу между двумя множествами. Этот метод используется по по умолчанию для сравения двух множеств или frozenset
assertEqual()
.Тест не будет пройденным если set1 или set2 не имеет метода
set.difference()
.New in version 2.7.
-
assertDictEqual
(expected, actual, msg=None)[source]¶ Проверяет, что два словаря равны. В противном случае, сообщение об ошибке будет содержать разницу между словарями. Этот метод будет использован по умолчанию для сравнения словарей при вызове
assertEqual()
.New in version 2.7.
Наконец,
TestCase
предоставляет следующие методы и атрибуты:-
fail
(msg=None)[source]¶ Сигнализирует о безусловном “падении” теста; в качестве сообщения об ошибке будет выведено 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
()[source]¶ Возвращает количество тестов, представленных этим тестовым объектом. Для экземпляров
TestCase
, это всегда будет1
.
-
defaultTestResult
()[source]¶ Возвращает экземпляр класса результата теста, который должен быть исопльзован для этого тестового случая (если других экземпляров результатов не предоставлено методу
run()
).Для экземпляров
TestCase
он всегда будет экземпляром классаTestResult
; подклассыTestCase
должны переопределять его по необходимости.
-
id
()[source]¶ Возвращает строку, идентифицирующую определённый тестовый случай. Обычно это полное имя тестового метода, включающее в себя имена модуля и класса.
-
shortDescription
()[source]¶ Возвращает описание теста или
None
, если описания нет. Реализация этого метода по умолчанию возвращает первую строку из строк документации для метода, если она есть, илиNone
.
-
addCleanup
(function, *args, **kwargs)[source]¶ Добавляет функцию, которая должна быть вызвана после
tearDown()
для уборки ресурсов, использованных в процессе тестирования. Функции будут вызываться в обратном порядке от их добавления (LIFO). Они вызываются с позиционными и именованными аргументами, переданными вaddCleanup()
.Если
setUp()
не срабатывает, то есть иtearDown()
не вызывается, то все добавленные при помощи этого метода функции всё равно будут вызываны.New in version 2.7.
-
doCleanups
()[source]¶ Этот мтеод вызывается в любом случае после
tearDown()
, илиsetUp()
, еслиsetUp()
вызывал исключение.Он отвечает за вызов всех отчищающих функций, добавленных методом
addCleanup()
. Если Вам нужно вызывать какие-то функции доtearDown()
, тогда Вы должны вызвать методdoCleanups()
сами.doCleanups()
вытаскивает (pop) методы из стека отчищающих функций по одной, так что она может быть вызвана в любое время.New in version 2.7.
-
-
class
unittest.
FunctionTestCase
(testFunc, setUp=None, tearDown=None, description=None)[source]¶ Этот класс реализует часть интерфейса
TestCase
, который позволяет исполнителю тестов провести тест, но не предоставляет методов, которые тестовый код может использовать для проверки и сообщении об ошибках. Он используется для создания тестовых случаев при помощи “наследственного” тестового кода, позволяя интегрировать его в основанные наunittest
тестирующие фреймворки.
Устаревшие псевдонимы¶
По историческим причинам, некоторые методы класса TestCase
имеют
один или более псевдонимов, которые на данный момент уже устарели. Следующая
таблица перечисляет корректные имена вместе с их устаревшими псевдонимами:
Имя метода Устаревшие псевдонимы assertEqual()
failUnlessEqual, assertEquals assertNotEqual()
failIfEqual assertTrue()
failUnless, assert_ assertFalse()
failIf assertRaises()
failUnlessRaises assertAlmostEqual()
failUnlessAlmostEqual assertNotAlmostEqual()
failIfAlmostEqual Deprecated since version 2.7: псевдонимы, перечисленные во втором столбце
Группировка тестов¶
-
class
unittest.
TestSuite
(tests=())[source]¶ Этот класс представляет коллекцию отдельных тестов и наборов тестов. Этот класс предоставляет интерфейс, необходимый для исполнителя тестов, чтобы он мог запускать эти тесты, как любые другие тесты. Запуск экземпляра
TestSuite
аналогичен итерации по набору тестов и запуску каждого теста по отдельности.Если передан аргумент tests, то он должен быть итерируемым объектом, состоящим отдельных тестов или наборов тестов, которые будут использоваться для конструирования набора тестов. Кроме того, есть дополнительные методы, которые позволяют позже добавить тест или набор тестов.
Объекты
TestSuite
ведут себя подобно объектамTestCase
, за исключением того, что они сами не реализуют тесты. Вместо этого, они используются для объединения тестов, которые должны быть запущенны одновременно, в группы. Вам доступно несколько методов для добавления тестов кTestSuite
:-
addTests
(tests)¶ Добавлет все тесты из итерируемых объектов
TestCase
иTestSuite
в тестовый набор.Это эквивалентно итерации по tests с вызовом
addTest()
для каждого элемента.
TestSuite
имеет следующие общие методы сTestCase
:-
run
(result)[source]¶ Запускает тесты, ассоциированные с этим набором, собирая результат в объект результата тестов, переданный через аргумент result. Обратите внимание, что в отличие от
TestCase.run()
,TestSuite.run()
требует передачи объекта результата тестов.
-
debug
()[source]¶ Запускает тесты, ассоциированные с этим набором, не собирая результат. Это позволяет исключениям, возбуждаемым тестами, доходить до вызывающего кода и его можно использовать для запуска тестов в отладчике.
-
countTestCases
()¶ Возвращает количество тестов, представленных этим объектом, включая все тесты и вложенные наборы.
-
__iter__
()¶ Тесты, собранные в
TestSuite
всегда доступны через итерации. Подклассы могут предоставлять тесты переопределив__iter__()
. Обратите внимание, что этот метод может быть вызван несколько раз для одного набора (например, когда подсчитывается количество тестов или они сравниваются на идентичность), так что тесты, возвращаемые методом, должны быть одинаковы для все повторных итераций.Changed in version 2.7: В ранних версиях
TestSuite
к тестам обращались на прямую, а не через итерации, так что переопределение__iter__()
не было достаточным для доступа к тестам.
При типичном использовании объекта
TestSuite
, методrun()
вызывается классомTestRunner
, а не конечным пользователем теста.-
Загрузка и выполнение тестов¶
-
class
unittest.
TestLoader
[source]¶ Класс
TestLoader
используется для создания набора тестов из классов и модулей. Обычно нет необходимости создавать экзмепляры этого класса; модульunittest
предоставляет экзмепляр, который можно использовать какunittest.defaultTestLoader
. Тем не менее, использование подкласса или экземпляра позволит Вам настроить некоторые свойства.Объекты
TestLoader
имеют следующие методы:-
loadTestsFromTestCase
(testCaseClass)[source]¶ Возвращает набор из всех тестов, содержащихся в
testCaseClass
, полученном изTestCase
.
-
loadTestsFromModule
(module)[source]¶ Возвращает набор из всех тестов, содержащихся в полученном модуле. Этот метод просматривает module в поисков классов, унаследованных от
TestCase
и создаёт экземпляр класса для каждого метода, определённого в классе.Note
Хотя использование иерархии из наследников класса
TestCase
может быть нормой в общих “стендах” и вспомогательных функциях, определение тестовых методов на базе классов, которые не предназначены для прямого вызова не будет нормально работать с этим методом. Но это может быть полезным в случае других “стендов”, которые определены в подклассах.Если модуль предоставляет функцию
load_tests
, то она будет вызвана для загрузки тестов. Это позволяет модулям настроить загрузку тестов. Это `load_tests protocol`_.Changed in version 2.7: Добавлена поддержка
load_tests
.
-
loadTestsFromName
(name, module=None)[source]¶ Возвращает набор из всех тестов для объекта, определённого строкой.
Определитель 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)[source]¶ - Похож на
loadTestsFromName()
, но принимает последовательность имён, а не - одно имя. Возвращает набор тестов, который поддерживает все тесты,
определённые для каждого имени.
- Похож на
-
getTestCaseNames
(testCaseClass)[source]¶ Возвращает отсортированную последовательность имён методов, найденных в testCaseClass, который должен быть подкласс от
TestCase
.
-
discover
(start_dir, pattern='test*.py', top_level_dir=None)[source]¶ Обнаруживает и возвращает все тестовые модули из определённого стартового каталога, проходясь и по всем подкаталогам. Будут загружены только те тестовые файлы, которые соответствуют 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
, чтобы отменить сортировку.
-
-
class
unittest.
TestResult
[source]¶ Этот класс используется для компиляции информации о том, какие тесты прошли успешно, а какие - нет.
Объекты
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
, которые были помечены как ожидающие ошибки, но ошибки не произошло.
-
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
()[source]¶ Возвращает
True
, если все тесты до сих пор были пройдены, в противном случае возвращаетFalse
.
-
stop
()[source]¶ Этот метод может быть вызван для того, чтобы сообщить о том, что выполнение текущего набора тестов должно быть прервано. Это достигается заданием значения
True
для атрибутаshouldStop
. ОбъектыTestRunner
должны учитывать этот флаг и прекращать своё выполнение без запуска дополнительных тестов.Например, эта возможность используется классом
TextTestRunner
для того, чтобы остановить выполнение тестов, когда пользователь прерывает выполнение тестов с клавиатуры. Интерактивные инструменты, предоставляющие реализациюTestRunner
могут использовать этот метод схожим образом.
Следующие методы класса
TestResult
используются для обслуживания внутренних структур данных и может быть расширен в подклассах для поддержки дополнительных возможностей вывода информации. Это особенно полезно при создании инструментов, которые поддерживают интерактивное оповещение о результатах в процессе выполнения тестов.-
stopTest
(test)[source]¶ Вызывается после того, как тестовый случай test был выполнен, вне зависимости от результата.
-
startTestRun
(test)[source]¶ Вызывается один раз перед запуском любого теста (видимо, перед началом выполнения всех тестов).
New in version 2.7.
-
addError
(test, err)[source]¶ Вызывается, когда тестовый случай test вызывает неожиданное исключение. err - это кортеж в форме, возвращаемой
sys.exc_info()
:(type, value, traceback)
.Реализация по умолчанию добавляет кортеж
(test, formatted_err)
к атрибутуerrors
экзмемпляра, где formatted_err - это отформатировання трассировка из err.
-
addFailure
(test, err)[source]¶ Вызывается, когда тестовый случай test сообщает о неудаче. err - это кортеж в форме, возвращаемой
sys.exc_info()
:(type, value, traceback)
.Реализация по умолчанию добавляет кортеж
(test, formatted_err)
к атрибутуfailures
экзмемпляра, где formatted_err - это отформатировання трассировка из err.
-
addSuccess
(test)[source]¶ Вызывается, когда тестовый случай test завершился удачно.
Реализация по умолчанию ничего не делает.
-
addSkip
(test, reason)[source]¶ Вызывается при пропуске тестового случая test. reason - это причина пропуска теста.
Реализация по умолчанию добавляет кортеж
(test, reason)
к атрибутуskipped
экземпляра.
-
addExpectedFailure
(test, err)[source]¶ Вызывается, когда тестовый случай test завершается с ошибкой, но он был помечен декоратором
expectedFailure()
.Реализация по умолчанию добавляет кортеж
(test, formatted_err)
к атрибутуexpectedFailures
экземпляра, где formatted_err - это отформатированная трассировка из err.
-
addUnexpectedSuccess
(test)[source]¶ Вызывается когда тестовый случай test был помечен декоратором
expectedFailure()
, но выполнен успешно.Реализация по умолчанию добавляет тест к атрибуту
unexpectedSuccesses
экземпляра.
-
-
class
unittest.
TextTestResult
(stream, descriptions, verbosity)[source]¶ Конкретная реализация
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)[source]¶ Базовая реализация выполнителя тестов, которая выводит результаты на стандартный вывод ошибок. У неё всего несколько настраеваемых параметров, но она очень проста. Графиеские приложения, котоыре запускают тесты, должны предоставить альтернативную реализацию.
-
_makeResult
()[source]¶ Этот метод возвращает экземпляр
TestResult
, используемый методомrun()
. Он не предназначен для непосредственного вызова, но может быть переопределён в подклассах для предоставления собственногоTestResult
._makeResult()
создаёт экземпляр из класса или вызываемого объекта, переданного в конструкторTextTestRunner
как аргументresultclass
. По умолчанию этоTextTestResult
. Экзмепляр будет создан со следующими аргументами:stream, descriptions, verbosity
-
-
unittest.
main
([module[, defaultTest[, argv[, testRunner[, testLoader[, exit[, verbosity[, failfast[, catchbreak[, buffer]]]]]]]]]])¶ Программа командной строки, которая загружает набор тестов из 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 имеют то же самое значение, что и соответствующие опции командной строки.
Вызов
main
возвращает экземпляр классаTestProgram
. Он хранит результаты вызова тестов в атрибутеresult
.Changed in version 2.7: Были добавлены аргументы exit, verbosity, failfast, catchbreak и buffer.
Протокол load_tests¶
New in version 2.7.
Модули или пакеты могут настроить процесс зарузки своих тестов при обычном
запуске тестов или при их обнаружении реализовав функцию load_tests
.
Если тестовый модуль определяет load_tests
, она будет вызвана методом
TestLoader.loadTestsFromModule()
со следующими аргументами:
load_tests(loader, standard_tests, 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
.
Note
Шаблон по умолчанию - 'test*.py'
. Этому соответствуют все файлы Python,
которые начинаются с 'test'
, но не соответствуют каталоги.
Шаблону вроде 'test*'
будет соответствовать как пакеты, так и
модули.
Если файл __init__.py
пакета определяет load_tests
, тогда эта
функция будет вызвана и поиск в пакете дальше вестить не будет. Функция load_tests
будет вызвана со следующими аргументами:
load_tests(loader, standard_tests, pattern)
Она должна вернуть TestSuite
, представляющий все тесты из пакета.
(standard_tests
будет содержать только тесты, собранные из
__init__.py
.)
Поскольку шаблон передаётся в load_tests
, пакет может спокойно продолжать
(и потециально изменять) обнаружение тестов. ‘Ничего не делающая’ фукнция
load_tests
для пакета будет выгдяеть так:
def load_tests(loader, standard_tests, pattern):
# каталог верхнего уровня кешируется в экзмепляре загрузчика
this_dir = os.path.dirname(__file__)
package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
standard_tests.addTests(package_tests)
return standard_tests
Стенды класса и модуля¶
Стенды уровня класса и модуля реализованы в TestSuite
. Когда
тестовый набор встечает тест из нового класса, тогда вызывается метод
tearDownClass()
из предыдущего класса (если он есть), за которым
вызывается метод setUpClass()
из нового класса.
Аналогично, если тест из модуля, отличного от предыдущего теста, тогда
вызывается метод tearDownModule
из предыдущего модуля, а затем
setUpModule
из нового.
После того, как все тесты были выполнены, запускается последний метод
tearDownClass
и tearDownModule
.
Обратите внимание, что общие стенды не очень хорошо работают с [потенциальными] возможностями, вроде распараллеливания тестов и нарушают изоляцию тестов. Поэтому они должны использоваться с осторожностью.
Упорядочивание тестов, создаваемых загрузчиком unittest`а заключается в
группировке всех тестов из одного модуля и класса. Это приводит к тому, что
setUpClass
/ setUpModule
(и т.д.) вызываются всего один раз на класс
или модуль. Если вы изменяете этот порядок, так что тесты из разных модулей
и классов могут быть перемешаны друг с другом, то эти функции создания общих
стендов могут вызываться несколько раз при одном запуске тестов.
Общие стенды не предназначены для работы с наборами тестов с нестандартным
порядком тестов. BaseTestSuite
всё ещё доступен для тех фреймворков,
которые не поддерживают общие стенды.
Если в одной из функций по созданию общих тестов возникает исключение, то
тест будет помечен как с ошибкой. Поскольку на этом этапе нет соответствующего
объекта теста, будет создан объект _ErrorHolder
(имеющий тот же самый
интерфейс, что и TestCase
) для отображения ошибки. Если Вы используете
обычный выполнитель тестов, тогда эта деталь для Вас ничего не значит, но
если Вы используете “авторский” фреймворк, это может на что-то повлиять.
setUpClass и tearDownClass¶
Они должны быть реализованы как методы класса:
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()
Вызывать эти методы Вы должны сами. Их реализация в TestCase
пустая.
Если возникает исключение при выполнении setUpClass
, тогда не запускаются
тесты класса и метод tearDownClass
. Пропускаемые классы тоже не
выполняют setUpClass
и tearDownClass
. Если исключением является
SkipTest
, тогда класс сообщит о том, что он был пропущен, а не что в
нём произошла ошибка.
setUpModule и tearDownModule¶
Они должны быть реализованы как функции:
def setUpModule():
createConnection()
def tearDownModule():
closeConnection()
Если возникает исключение при выполнении setUpModule
, тогда не запускаются
тесты модуля и метод tearDownModule
. Если исключением является
SkipTest
, тогда модуль сообщит о том, что он был пропущен, а не что в
нём произошла ошибка.
Обработка сигналов¶
Опции командной строки -c/--catch
, как и параметр
catchbreak
функции unittest.main()
, позволяет провести более
дружественный перехват control-C в процессе выполнения тестов. В таком случае
control-C позволит завершиться выполняемому тесту, после чего выполнение
тестов будет прекращено и будет выведен результат о тех тестах, которые
успели пройти. Повторное нажатие control-c вызовет KeyboardInterrupt
как обычно.
Обработка сигнала control-c пытается сохранить совместимость с кодом тестов,
которые устанавливают свои собственные обработчики signal.SIGINT
.
Если вызывается обработчик unittest
, а не установленный обработчик
signal.SIGINT
, то есть он был заменён в тесте системным или ему
была делигирована обработка сигнала, тогда вызывается стандартный обработчик.
Это ожидаемое поведение для кода, который замещает установленный обработчик
и передаёт обработку ему. Для конкретных тестов, которым надо отключить
обработку ``unittest``ом control-c, можно использовать декоратор
removeHandler()
.
‘’не понял, если честно, предыдущий абзац(‘’
Есть несколько функций для создателей фреймворков, чтобы активировать обработку control-c в тестовых фреймворках.
-
unittest.
installHandler
()[source]¶ IУстанавлвает обработчик control-c. Когда получается сигнал
signal.SIGINT
(обычно в ответ на нажатие пользователем control-c), вызываются все зарегистрированные результаты методаstop()
.New in version 2.7.
-
unittest.
registerResult
(result)[source]¶ Регистрирует объект
TestResult
для обработки control-c. Регистрация результата сохраняет слабую ссылку на результат, так что это не предохраняет от уборки результата сборщиком мусора.Регистрация объекта
TestResult
не имеет побочных эффектов, если обработка control-c не активированы, так что тестовые фреймворки могут без условий регистрировать все результаты, которые они создают, вне зависимости от того, активирована обработка или нет.New in version 2.7.
-
unittest.
removeResult
(result)[source]¶ Убирает зарегистрированный результат. После того, как результат удалён, тогда метод
stop()
уже не будет вызван для этого объекта в ответ на control-c.New in version 2.7.
-
unittest.
removeHandler
(function=None)[source]¶ При вызове без аргументов эта функция удаляет обработчик control-c, если он был установлен. Эта функция так же может быть использована как декоратор теста для временного удаления обработчика во время выполнения теста:
@unittest.removeHandler def test_signal_handling(self): ...
New in version 2.7.