Как написать unittest, который не проходит, только если функция не выдает ожидаемое исключение?
python
unit-testing
exception
exception-handling
Дэрил Спитцер
источник
источник
myfunc
вам необходимо добавить их в качестве аргументов в вызов assertRaises. Смотрите ответ Дэрила Спитцера.self.assertRaises(TypeError, mymod.myfunc)
. Вы можете найти полный список встроенных исключений здесь: docs.python.org/3/library/exceptions.html#bltin-exceptionsself.assertRaises(SomeCoolException, Constructor, arg1)
Начиная с Python 2.7 вы можете использовать менеджер контекста, чтобы получить реальный объект Exception:
http://docs.python.org/dev/library/unittest.html#unittest.TestCase.assertRaises
В Python 3.5 , вы должны обернуть
context.exception
вstr
противном случае вы получитеTypeError
источник
context.exception
не дает сообщение; это тип.import unittest2
, вам нужно использоватьstr()
, то естьself.assertTrue('This is broken' in str(context.exception))
.Код в моем предыдущем ответе может быть упрощен до:
И если функция принимает аргументы, просто передайте их в assertRaises следующим образом:
источник
2.7.15
. Еслиafunction
вself.assertRaises(ExpectedException, afunction, arg1, arg2)
это инициализатор класса, вам нужно передатьself
в качестве первого аргумента, например,self.assertRaises(ExpectedException, Class, self, arg1, arg2)
Короткий ответ:
Используйте
self.assertRaises
метод как менеджер контекста:демонстрация
Подход наилучшей практики довольно легко продемонстрировать в оболочке Python.
unittest
библиотекаВ Python 2.7 или 3:
В Python 2.6 вы можете установить бэкпорт
unittest
библиотеки 2.7 , называемый unittest2 , и просто псевдоним, который будет следующимunittest
:Пример тестов
Теперь вставьте в вашу оболочку Python следующий тест безопасности типов Python:
Тест один использует
assertRaises
в качестве диспетчера контекста, который гарантирует, что ошибка правильно перехвачена и исправлена во время записи.Мы могли бы также написать это без менеджера контекста, см. Тест два. Первым аргументом будет тип ошибки, который вы ожидаете вызвать, второй аргумент, функция, которую вы тестируете, а остальные аргументы и аргументы ключевых слов будут переданы этой функции.
Я думаю, что гораздо проще, удобочитаемее и удобнее в использовании просто использование диспетчера контекста.
Запуск тестов
Чтобы запустить тесты:
В Python 2.6 вам, вероятно, понадобится следующее :
И ваш терминал должен вывести следующее:
И мы видим, что, как мы и ожидаем, попытка добавить a
1
и'1'
результат вTypeError
.Для более подробного вывода попробуйте это:
источник
Ваш код должен следовать этому шаблону (это тест стиля модуля unittest):
На Python <2.7 эта конструкция полезна для проверки конкретных значений в ожидаемом исключении. Функция unittest
assertRaises
только проверяет, возникло ли исключение.источник
assertRaises
вы получите ОШИБКУ вместо ОТКАЗА.от: http://www.lengrand.fr/2011/12/pythonunittest-assertraises-raises-error/
Во-первых, вот соответствующая (все еще dum: p) функция в файле dum_function.py:
Вот тест, который нужно выполнить (вставлен только этот тест):
Теперь мы готовы проверить нашу функцию! Вот что происходит при попытке запустить тест:
TypeError вызывается actullay и генерирует тестовый сбой. Проблема в том, что это именно то поведение, которое мы хотели: с.
Чтобы избежать этой ошибки, просто запустите функцию, используя лямбду в тестовом вызове:
Окончательный вывод:
Отлично !
... и для меня тоже идеально !!
Большое спасибо господин Жюльен Ленгранд-Ламберт
Этот тест assert фактически возвращает ложный положительный результат . Это происходит потому, что лямбда внутри 'assertRaises' является единицей, которая вызывает ошибку типа, а не проверенной функцией.
источник
self.assertRaises(TypeError, df.square_value(self.false_int))
вызывает метод и возвращает результат. Вам нужно передать метод и любые аргументы и позволить юнит-тесту вызвать его:self.assertRaises(TypeError, df.square_value, self.false_int)
Вы можете создать свой собственный,
contextmanager
чтобы проверить, возникло ли исключение.И тогда вы можете использовать
raises
как это:Если вы используете
pytest
, эта вещь уже реализована. Ты можешь сделатьpytest.raises(Exception)
:Пример:
И результат:
источник
unittest
модуля!Я использую doctest [1] почти везде, потому что мне нравится тот факт, что я документирую и тестирую свои функции одновременно.
Посмотрите на этот код:
Если вы поместите этот пример в модуль и запустите его из командной строки, оба контрольных примера будут оценены и проверены.
[1] Документация по Python: 23.2 doctest - тестирование интерактивных примеров Python
источник
Я только что обнаружил, что библиотека Mock предоставляет метод assertRaisesWithMessage () (в своем подклассе unittest.TestCase), который будет проверять не только то, что вызывается ожидаемое исключение, но и то, что оно вызывается с ожидаемым сообщением:
источник
Здесь много ответов. Код показывает, как мы можем создать Исключение, как мы можем использовать это исключение в наших методах и, наконец, как вы можете проверить в модульном тесте правильные возбуждаемые исключения.
источник
Вы можете использовать assertRaises из модуля unittest
источник
Поскольку я не видел подробного объяснения о том, как проверить, получено ли конкретное исключение из списка принятых с помощью контекстного менеджера, или других подробностей исключения, я добавлю свои (проверено на python 3.8).
Если я просто хочу проверить, например
TypeError
, что функция поднимается , я бы написал:Если я хочу проверить, что функция вызывает или
TypeError
илиIndexError
, я бы написал: с self.assertRaises ((TypeError, IndexError)): function_raising_some_exception (параметры)И если я захочу узнать больше подробностей об Исключении, я могу уловить его в таком контексте:
источник
Несмотря на то, что все ответы в порядке, я искал способ проверить, вызвала ли функция исключение, не полагаясь на рамки модульного тестирования и не создавая тестовые классы.
В итоге я написал следующее:
И это не на правильной линии:
источник