如何使用请求库测试 python 中的重试尝试
How to test Retry attempts in python using the request library
我有以下内容:
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
retry_strategy = Retry(
total=3,
status_forcelist=[429, 500, 502, 503, 504],
method_whitelist=["HEAD", "GET", "OPTIONS"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)
response = http.get("some_endpoint")
单元测试如何有效地重试 N 次(在本例中为 3 次)?
我也有同样的疑问,但我找不到任何建议,甚至在 Stack Overflow 上也找不到。但我真的很想确保它按我预期的那样工作...
我花了一段时间才弄清楚在哪里以及如何修补 urllib3
以正确测试它,但这是我迄今为止想出的最好的解决方案,为您节省了几个小时的研究时间:
import urllib3
from http.client import HTTPMessage
from unittest.mock import ANY, Mock, patch, call
import requests
import pytest
def request_with_retry(*args, **kwargs):
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries=urllib3.Retry(
raise_on_status=False,
total=kwargs.pop("max_retries", 3),
status_forcelist=[429, 500, 502, 503, 504], # The HTTP response codes to retry on
allowed_methods=["HEAD", "GET", "PUT", "DELETE", "OPTIONS"], # The HTTP methods to retry on
))
session.mount("https://", adapter)
session.mount("http://", adapter)
return session.request(*args, **kwargs)
@patch("urllib3.connectionpool.HTTPConnectionPool._get_conn")
def test_retry_request(getconn_mock):
getconn_mock.return_value.getresponse.side_effect = [
Mock(status=500, msg=HTTPMessage()),
Mock(status=429, msg=HTTPMessage()),
Mock(status=200, msg=HTTPMessage()),
]
r = request_with_retry("GET", "http://any.url/testme", max_retries=2)
r.raise_for_status()
assert getconn_mock.return_value.request.mock_calls == [
call("GET", "/testme", body=None, headers=ANY),
call("GET", "/testme", body=None, headers=ANY),
call("GET", "/testme", body=None, headers=ANY),
]
(注意:如果您多次调用此方法,那么您可能只想初始化会话对象一次,而不是每次发出请求时!)
我有以下内容:
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
retry_strategy = Retry(
total=3,
status_forcelist=[429, 500, 502, 503, 504],
method_whitelist=["HEAD", "GET", "OPTIONS"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)
response = http.get("some_endpoint")
单元测试如何有效地重试 N 次(在本例中为 3 次)?
我也有同样的疑问,但我找不到任何建议,甚至在 Stack Overflow 上也找不到。但我真的很想确保它按我预期的那样工作...
我花了一段时间才弄清楚在哪里以及如何修补 urllib3
以正确测试它,但这是我迄今为止想出的最好的解决方案,为您节省了几个小时的研究时间:
import urllib3
from http.client import HTTPMessage
from unittest.mock import ANY, Mock, patch, call
import requests
import pytest
def request_with_retry(*args, **kwargs):
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries=urllib3.Retry(
raise_on_status=False,
total=kwargs.pop("max_retries", 3),
status_forcelist=[429, 500, 502, 503, 504], # The HTTP response codes to retry on
allowed_methods=["HEAD", "GET", "PUT", "DELETE", "OPTIONS"], # The HTTP methods to retry on
))
session.mount("https://", adapter)
session.mount("http://", adapter)
return session.request(*args, **kwargs)
@patch("urllib3.connectionpool.HTTPConnectionPool._get_conn")
def test_retry_request(getconn_mock):
getconn_mock.return_value.getresponse.side_effect = [
Mock(status=500, msg=HTTPMessage()),
Mock(status=429, msg=HTTPMessage()),
Mock(status=200, msg=HTTPMessage()),
]
r = request_with_retry("GET", "http://any.url/testme", max_retries=2)
r.raise_for_status()
assert getconn_mock.return_value.request.mock_calls == [
call("GET", "/testme", body=None, headers=ANY),
call("GET", "/testme", body=None, headers=ANY),
call("GET", "/testme", body=None, headers=ANY),
]
(注意:如果您多次调用此方法,那么您可能只想初始化会话对象一次,而不是每次发出请求时!)