Playwright进阶指南 (5):拦截与模拟网络请求
【摘要】 Playwright测试进阶:掌握网络请求拦截与Mock实战。详解如何精准控制请求参数、模拟API响应、构造异常场景及替换资源,提升测试效率与稳定性。附动态Mock、性能优化技巧及分层数据管理方案,带你构建高可控性测试环境。
在现代Web应用测试中,精准控制网络请求是提升测试效率和可靠性的重要因素。
Playwright 提供了强大的网络请求拦截与Mock能力,让你能够:
-
拦截并修改 请求头、参数、URL -
模拟API响应 无需依赖真实后端 -
构造异常场景 测试边缘情况 -
加速测试执行 避免真实网络延迟
一、核心概念:路由与请求处理
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context()
page = context.new_page()
# 核心路由拦截方法
def handle_route(route):
if"api/v1/user"in route.request.url:
# 在此处处理特定请求
...
route.continue_()
# 注册全局路由处理器
page.route("**/*", handle_route)
page.goto("https://your-app.com")
二、实战技巧:4种典型应用场景
场景1:修改请求参数(如添加认证Token)
def handle_route(route):
headers = route.request.headers
headers["Authorization"] = "Bearer mock_token" # 注入模拟Token
route.continue_(headers=headers) # 修改后继续请求
场景2:拦截特定请求返回Mock数据
def mock_user_api(route):
if route.request.url.endswith("/api/user"):
# 构造JSON响应
route.fulfill(
status=200,
content_type="application/json",
body=json.dumps({"name": "测试用户", "id": 1001})
)
else:
route.continue_()
场景3:模拟网络异常(测试错误处理)
def simulate_failure(route):
if "payment-api" in route.request.url:
# 返回500错误
route.fulfill(status=500, body="Service Unavailable")
else:
route.continue_()
场景4:替换资源文件(如修改CSS/JS)
def replace_styles(route):
if route.request.url.endswith(".css"):
route.fulfill(
body="* { color: red !important; }" # 强制所有文字变红
)
三、高级技巧:动态Mock服务
结合 pytest
实现自动化Mock:
import pytest
from playwright.sync_api import Page
@pytest.fixture
def setup_mock(page: Page):
def mock_handler(route):
if"/data"in route.request.url:
# 根据请求参数动态响应
params = route.request.url.split("?")[1]
route.fulfill(body=f"Response to {params}")
page.route("**/api/*", mock_handler)
yield
def test_dynamic_mock(setup_mock, page: Page):
page.goto("https://app.com")
# 测试将自动获得动态Mock响应
四、调试技巧:实时监控网络请求
# 监听所有请求
page.on("request", lambda req: print(f">> {req.method} {req.url}"))
# 监听所有响应
page.on("response", lambda res: print(f"<< {res.status} {res.url}"))
# 捕获请求失败
page.on("requestfailed", lambda req: print(f"!! {req.url} {req.failure}"))
五、性能优化:选择性拦截
避免不必要的处理开销:
# 精确匹配URL
page.route("https://api.example.com/v1/users", handler)
# 使用正则表达式
page.route(re.compile(r".*\.(jpg|png)$"), lambda r: r.abort()) # 阻止图片加载
# 按请求类型过滤
def handle_post(route):
if route.request.method == "POST":
...
六、Mock数据管理建议
-
分层管理: -
基础Mock:放置在 conftest.py
-
场景Mock:封装为独立模块 -
数据工厂: def generate_user_data(role="user"):
return {
"name": f"test_{role}",
"permissions": ["read"] if role=="user" else ["read","write"]
} -
使用模板引擎: from jinja2 import Template
template = Template('{"user": "{{ name }}", "role": "{{ role }}"}')
route.fulfill(body=template.render(name="admin", role="superuser"))
七、注意事项
-
作用域控制:
-
使用 browser_context.route()
实现上下文隔离 -
通过 page.unroute()
及时清理避免污染 -
真实请求验证:
# 临时禁用Mock进行验证
with page.expect_request("**/api/data") as req_info:
page.click("#refresh-btn")
request = req_info.value
assert request.post_data == '{"valid":true}' -
资源释放:
# 测试结束后移除路由
def teardown():
page.remove_route(handler)
最佳实践提示:
将核心Mock逻辑封装为独立模块,通过环境变量控制Mock开关:if os.getenv("MOCK_MODE") == "enable":
apply_mocks(page)
通过灵活运用Playwright的请求拦截能力,您可以创建一个完全可控的测试环境,从而显著提高测试用例的稳定性和执行速度。这项技术特别适用于以下场景:
1. 微服务架构的集成测试
2. 模拟第三方依赖的异常情况
3. 验证前端性能优化
4. 在CI/CD流水线中进行无后端测试
掌握这些技巧,将使你的自动化测试水平达到新的高度!
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)