pytest, raise_for_status with Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>

Posted

技术标签:

【中文标题】pytest, raise_for_status with Failed: DID NOT RAISE <class \'requests.exceptions.HTTPError\'>【英文标题】:pytest, raise_for_status with Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>pytest, raise_for_status with Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'> 【发布时间】:2020-12-03 22:53:22 【问题描述】:

这是为了记录我偶然发现的东西。

这不起作用。 try/except/else 子句将吞噬r.raise_for_status() 生成的异常。

import requests
from requests.exceptions import HTTPError
import pytest
import logging

def fetch(url):
    """HTTP request"""
    try:
        r = requests.get(url)
        r.raise_for_status()
    except HTTPError as err:
        logging.warning(f'Fetching url failed err')
    else:
        print(r.data)


def test_fetch(mocker):
    """Test."""
    mock_response = mocker.Mock(requests.Response)
    expected_exc = HTTPError()
    mock_response.raise_for_status.side_effect = expected_exc
    mocker.patch.object(requests, 'get')
    requests.get.return_value = mock_response
    r = fetch('http://httpbin.org/status/400')
    with pytest.raises(HTTPError) as err_msg:
        r.raise_for_status()

从pytest收到的错误信息是


example.py F                                                                                                                      [100%]

====================================================================== FAILURES =======================================================================
_____________________________________________________________________ test_fetch ______________________________________________________________________

mocker = <pytest_mock.plugin.MockFixture object at 0x1095cd100>

    def test_fetch(mocker):
        """Test."""
        mock_response = mocker.Mock(requests.Response)
        expected_exc = HTTPError()
        mock_response.raise_for_status.side_effect = expected_exc
        mocker.patch.object(requests, 'get')
        requests.get.return_value = mock_response
        with pytest.raises(HTTPError) as err_msg:
>           fetch('http://httpbin.org/status/400')
E           Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>

example.py:25: Failed
------------------------------------------------------------------ Captured log call ------------------------------------------------------------------
WARNING  root:example.py:12 Fetching url failed
=============================================================== short test summary info ===============================================================
FAILED example.py::test_fetch - Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>
================================================================== 1 failed in 0.20s ==================================================================

我在下面给出了答案。

【问题讨论】:

【参考方案1】:

如果你真的觉得,你需要在这里测试 raise_for_status。有必要再次引发异常。

import requests
from requests.exceptions import HTTPError
import pytest
import logging

def fetch(url):
    """HTTP request"""
    try:
        r = requests.get(url)
        r.raise_for_status()
    except HTTPError as err:
        logging.warning(f'Fetching url failed err')
        # HERE raise again.
        raise
    else:
        print(r.data)


def test_fetch(mocker):
    """Test."""
    mock_response = mocker.Mock(requests.Response)
    expected_exc = HTTPError()
    mock_response.raise_for_status.side_effect = expected_exc
    mocker.patch.object(requests, 'get')
    requests.get.return_value = mock_response
    with pytest.raises(HTTPError) as err_msg:
        fetch('http://httpbin.org/status/400')

【讨论】:

【参考方案2】:

而不仅仅是在除了块之外进行登录 另外,加注。

except HTTPError as err:
    logging.warning(f'Fetching url failed err')
    raise

因为:pytest.raises 寻找 raise 条件而不是异常。

【讨论】:

以上是关于pytest, raise_for_status with Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>的主要内容,如果未能解决你的问题,请参考以下文章

pytest 配置文件

Python - pytest

pytest---pytest.ini配置文件

pytest学习和使用18-pytest.ini配置文件如何使用?

『德不孤』Pytest框架 — 4.pytest.ini文件和用例执行的顺序

pytest-18-配置文件pytest.ini