8

Как правильно проверить, что исключение возникает в pytest?

9

Описание проблемы

Я столкнулся с проблемой при использовании библиотеки 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 ответ(ов)

3

Да, вы имеете в виду что-то вроде этого:

def test_raises():
    with pytest.raises(Exception) as exc_info:   
        raise Exception('некоторая информация')
    # эти утверждения идентичны; вы можете использовать любое из них   
    assert exc_info.value.args[0] == 'некоторая информация'
    assert str(exc_info.value) == 'некоторая информация'

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

0

Вы можете попробовать следующий код для тестирования обработки исключений с использованием библиотеки 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 в вашем тестовом файле.

0

Этот код - решение, которое мы используем для тестирования корректности входных данных.

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.

0

Если вы хотите проверить наличие определенного типа ошибки, вы можете использовать комбинацию try, except и raise. Вот пример кода для проверки на TypeError:

#-- проверяем на TypeError
try:
    myList.append_number("a")
    assert False  # Если код выше не выбросит исключение, данное условие сработает
except TypeError:
    pass  # Ожидаем, что возникнет TypeError
except Exception:  # Ловим все остальные исключения
    assert False  # Если возникло другое исключение, тест не проходит

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

0

Добавляю еще одно "глупое" предложение, так как не вижу его в существующих ответах. В принципе, вы можете инициализировать переменную ошибки как None, выполнить действие в блоке try/except, а затем проверить класс/значение переменной ошибки после этого:

e = None

try:
    blah()
except Exception as exc:
    e = exc

assert e.__class__ == ValueError  # или любое другое ожидаемое значение
assert str(e) == "ожидаемое сообщение"

Этот метод позволяет вам аккуратно обрабатывать ошибки и проверять их тип и сообщение.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь