Как правильно проверить, что исключение возникает в pytest?
Описание проблемы
Я столкнулся с проблемой при использовании библиотеки pytest
для тестирования функции, которая вызывает исключение ZeroDivisionError
. В моем тесте test_whatever
я пытаюсь отловить это исключение и вызвать pytest.fail()
, чтобы зарегистрировать ошибку.
Вот мой код:
# coding=utf-8
import pytest
def whatever():
return 9/0
def test_whatever():
try:
whatever()
except ZeroDivisionError as exc:
pytest.fail(exc, pytrace=True)
Когда я запускаю тест, я получаю следующий вывод:
================================ test session starts =================================
platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
plugins: django, cov
collected 1 items
pytest_test.py F
====================================== FAILURES ======================================
___________________________________ test_whatever ____________________________________
def test_whatever():
try:
whatever()
except ZeroDivisionError as exc:
> pytest.fail(exc, pytrace=True)
E Failed: integer division or modulo by zero
pytest_test.py:12: Failed
============================== 1 failed in 1.16 seconds ==============================
Как я могу сделать так, чтобы pytest
выводил трассировку стека, чтобы я мог увидеть, где именно в функции whatever
возникло исключение?
5 ответ(ов)
Да, вы имеете в виду что-то вроде этого:
def test_raises():
with pytest.raises(Exception) as exc_info:
raise Exception('некоторая информация')
# эти утверждения идентичны; вы можете использовать любое из них
assert exc_info.value.args[0] == 'некоторая информация'
assert str(exc_info.value) == 'некоторая информация'
В этом примере мы используем pytest
для проверки того, что исключение вызывает ожидаемое сообщение. Вы можете использовать любой из двух способов для проверки сообщения об ошибке.
Вы можете попробовать следующий код для тестирования обработки исключений с использованием библиотеки pytest
:
def test_exception():
with pytest.raises(Exception) as excinfo:
function_that_raises_exception()
assert str(excinfo.value) == 'some info'
В этом примере, функция function_that_raises_exception()
должна вызывать исключение, и мы проверяем, что сообщение этого исключения соответствует ожидаемым данным ('some info'). Убедитесь, что вы импортировали pytest
в вашем тестовом файле.
Этот код - решение, которое мы используем для тестирования корректности входных данных.
def test_date_invalidformat():
"""
Тестирует, вызывает ли неправильный формат даты исключение ValueError
"""
date = "06/21/2018 00:00:00"
with pytest.raises(ValueError):
app.func(date) # функция, которую мы тестируем
Обратите внимание на использование pytest.raises
, которое позволяет проверить, будет ли вызвано исключение определенного типа при выполнении кода. Подробности можно найти в документации pytest: https://docs.pytest.org/en/latest/reference.html#pytest-raises.
Если вы хотите проверить наличие определенного типа ошибки, вы можете использовать комбинацию try
, except
и raise
. Вот пример кода для проверки на TypeError
:
#-- проверяем на TypeError
try:
myList.append_number("a")
assert False # Если код выше не выбросит исключение, данное условие сработает
except TypeError:
pass # Ожидаем, что возникнет TypeError
except Exception: # Ловим все остальные исключения
assert False # Если возникло другое исключение, тест не проходит
Таким образом, если метод append_number
вызовет TypeError
при попытке передать строку, тест пройдет, а если возникнет другое исключение или код выполнится без ошибки, тест не пройдет.
Добавляю еще одно "глупое" предложение, так как не вижу его в существующих ответах. В принципе, вы можете инициализировать переменную ошибки как None
, выполнить действие в блоке try/except
, а затем проверить класс/значение переменной ошибки после этого:
e = None
try:
blah()
except Exception as exc:
e = exc
assert e.__class__ == ValueError # или любое другое ожидаемое значение
assert str(e) == "ожидаемое сообщение"
Этот метод позволяет вам аккуратно обрабатывать ошибки и проверять их тип и сообщение.
Как протестировать, что функция Python вызывает исключение?
Вручную вызов (бросание) исключения в Python
Поймать и вывести полный трейсбек исключения в Python без остановки/выхода из программы
Как напечатать исключение в Python?
Как проверить, существует ли переменная?