首页app攻略RequestParam高效使用攻略 requests怎么模拟https请求

RequestParam高效使用攻略 requests怎么模拟https请求

圆圆2025-08-14 23:02:06次浏览条评论

掌握 requests-mock:高效模拟动态 URL 请求与响应序列本教程研究如何高效使用 requests-mock 库模拟 Python 中请求库发起的 HTTP 请求,特别是针对包含动态参数(如页码)的 URL。文章将详细介绍如何利用正则表达式匹配 URL,并通过 side_effect 参数模拟一系列不同的响应,从而在测试环境中准确控制外部 API 调用的行为,确保测试的隔离性和自动化。

在开发与 api 的 python 交互应用时,进行单元测试和集成测试关键。然而,直接调用外部 api 不仅会增加测试时间、消耗网络资源,还可能受到 api 速率或不可预测的网络波动影响,导致测试结果不稳定。为了解决这些问题,模拟(mocking)外部 http 请求成为一种标准实践。

本教程将重点放在如何使用 requests-mock 库来模拟请求库的 HTTP 请求。我们将特别关注处理动态 URL 的场景,例如分页 API调用,并演示如何精确控制模拟响应的序列,以确保测试逻辑的错误。为什么需要模拟HTTP请求?隔离性: 将被测代码与外部依赖(如网络、数据库)隔离,确保测试只关注代码本身的逻辑。速度:避免实际的网络延迟,显着测试执行速度。中断:消除外部服务不可用、网络不确定等不确定因素对测试结果的影响。场景模拟:轻松模拟各种成功、失败、异常或数据特定返回的场景,这些场景在真实环境中可能难以恢复。引入 requests-mock

requests-mock 是一个强大且易于使用的 Python 功能库,专门用于模拟请求库发出任何 HTTP 请求。它通过在 requests 内部注册框架来实现请求的拦截和响应的模拟,而吸收修改代码。

首先,确保你已经安装了 requests-mock:pip install requests-mock 登录后复制核心概念:URL 匹配与正则说明

在 API 调用场景中,URL 并不固定不变,而是包含动态参数,例如分页 API 的页面应用码 (?page=1, ?page=2)。requests-mock 允许使用正则表达式来匹配此类动态 URL,从而用一个规则覆盖多个可能的请求。

考虑以下用于从 SWAPI(星球大战 API)获取人物列表的函数:import requestsfrom http import HTTPStatusdef consuming_api_swapi_index_page(initial_page: int = 1): quot;quot;quot;Swapi 索引页.quot;quot;quot; check = HTTPStatus.OK results = [] current_page = initial_page while check == HTTPStatus.OK: response = requests.get( f'https://swapi.dev/api/people/?page={current_page}' ) # 这里的response.url是关键,它会是实际请求的URL results.append(url := response.url) print(url) check = response.status_code current_page = 1 return results 登录后复制

这个函数会循环调用API,直到收到非200的状态码。在测试中,我们需要模拟一系列请求,每个请求的URL中的页面参数都会递增。

我们可以使用 re.compile 来创建一个正则表达式模式,以匹配所有页码的 URL:import reimport requests_mock# 定义匹配所有页码的正则表达式matcher = re.compile(rquot;https://swapi.dev/api/people/\?page=\d quot;)# 在测试中,requests-mock 会拦截所有匹配此模式的 GET 请求# m 是一个 requests_mock.Mocker 对象,通常通过 pytest 的fixture提供# m.register_uri('GET', matcher, text='Mocked Response')登录后复制

关键点:当requests-mock拦截到一个匹配匹配器的请求时,它会使用你提供的模拟响应。更重要的是,response.url属性会自动设置为实际发起请求的URL,而不是匹配模式本身。这意味着如果请求是https://swapi.dev/api/people/?page=1,那么response.url就会是 https://swapi.dev/api/people/?page=1,这正是我们函数逻辑所需要的。 模拟动态响应序列:利用副作用控制流程

对于像 consuming_api_swapi_index_page 这样依赖于连续请求状态(如循环终止条件)的函数,仅仅提供一个静态响应是不够的。我们需要模拟一系列不同的操作,例如前几页返回成功状态,最后一页返回非成功状态则终止循环。

requests-mock 提供了 side_effect 参数,它允许你提供一个响应字典列表。每次匹配到请求时,requests-mock 都会按顺序从列表中取出一个响应来返回。当列表进一步后,后续的请求将不再被模拟(除非有其他规则匹配)。

让上述 easing_api_swapi_index_page 函数在测试中正确执行并终止,我们需要模拟 10个成功的请求(对应页码 1 到 10),然后模拟一个非 200 的请求来结束循环。

以下是一个完整的测试案例:import requestsimport requests_mockimport refrom http import HTTPStatus# 假设 consuming_api_swapi_index_page 函数已定义如上def test_consuming_api_swapi_index_page(requests_mock) -gt; None: quot;quot;quot;Test it.quot;quot;quot;# 期望的 URL 列表 Expected_urls = [ 'https://swapi.dev/api/people/?page=1', 'https://swapi.dev/api/people/?page=2', 'https://swapi.dev/api/people/?page=3', 'https://swapi.dev/api/people/?page=4', 'https://swapi.dev/api/people/?page=5', 'https://swapi.dev/api/people/?page=6', 'https://swapi.dev/api/people/?page=7', 'https://swapi.dev/api/people/?page=8', 'https://swapi.dev/api/people/?page=9', 'https://swapi.dev/api/people/?page=10', ] # 定义匹配所有页码的正则表达式 matcher = re.compile(rquot;https://swapi.dev/api/people/\?page=\d quot;) # 准备 side_effect 响应列表 # 前 10 个请求返回 HTTPStatus.OK (200) # 第 11 个请求返回 HTTPStatus.NOT_FOUND (404) 以终止循环 mock_responses = [] for _ in range(10):mock_responses.append({'status_code': HTTPStatus.OK, 'json': {'结果': []}}) # 模拟一个空结果,如果函数需要解析json mock_responses.append({'status_code': HTTPStatus.NOT_FOUND}) # 终止循环的响应 # 注册URI,使用side_effect提供响应序列 requests_mock.get(matcher, side_effect=mock_responses) # 调用被测试函数actual_urls = easing_api_swapi_index_page() # 断言结果是否符合预期assert实际 url == 预期 url

# 注意:如果使用 pytest,requests_mock 会作为 Fixture 自动提供。#如果不使用 pytest,则需要手动创建 Mocker 实例并用语句使用:# import requests_mock# with requests_mock.Mocker() as m:# m.get(matcher, side_effect=mock_responses)#actual_urls = easing_api_swapi_index_page()#assertactual_urls == Expected_urls登录后复制

在这个例子中:我们定义了一个正则表达式匹配器来匹配所有页面参数的URL。mock_responses列表包含了10个成功响应(状态码200)和一个非成功响应(状态码404)。当消费_api_swapi_index_page函数第一次调用requests.get时,requests-mock会拦截它,并返回mock_responses列表中的第一个响应。函数继续循环,每次调用requests.get都会从mock_responses中取出下一个响应,直到第11 次调用时,返回 404 状态码,从而使函数跳出循环。response.url 在每次调用中都会自动设置为实际请求的 URL(如 https://swapi.dev/api/people/?page=1,然后是 page=2,依此类推),完美地满足了 results.append(url := response.url) 的需求注意事项与最佳实践测试程度:接近在单元测试层面模拟外部依赖,保持测试的快速和独立。明确的模拟范围:使用requests-mock时,确保你只模拟了你想要控制的请求。对于未注册的请求,requests-mock默认会允许它们通过,除非你明显地禁用网络(requests_mock.Mocker(kw='disable_net_connect=True'))。模拟所有相关属性:除了status_code和url,你可能还需要模拟json()、text、headers 等 Response 对象的其他属性,以确保被测函数能够正常工作。错误和异常场景: 利用 side_effect 或注册不同的 URI 自定义匹配器:对于更复杂的匹配逻辑,requests-mock也支持匹配自定义器函数,提供了极高的灵活性,但对于大多数动态URL场景,正则表达式已经足够了。总结

requests-mock是Python中进行HTTP请求模拟的强大工具。通过结合正则表达式进行灵活的URL匹配,并利用side_effect参数来模拟序列化的响应,我们可以精确地控制外部API调用的行为,从而编写出隔离性好、执行快且结果可靠的测试。掌握这些技巧将显着提升你的测试效率和代码质量。

以上就是掌握requests-mock:模拟高效动态URL请求与响应序列的详细内容,更多请关注乐哥常识网其他相关文章!

掌握 request
html缩小后文字错乱 html文字缩进怎么设置
相关内容
发表评论

游客 回复需填写必要信息