写点什么

Playwright 进阶篇 (5) | 网络请求拦截与 Mock

  • 2025-08-22
    黑龙江
  • 本文字数:2140 字

    阅读完需:约 7 分钟

在现代 Web 应用测试中,精准控制网络请求是提升测试效率和可靠性的关键。Playwright 提供了强大的网络请求拦截与 Mock 能力,让你能够:


  • 拦截并修改 请求头、参数、URL

  • 模拟 API 响应 无需依赖真实后端

  • 构造异常场景 测试边缘情况

  • 加速测试执行 避免真实网络延迟


测试开发全景图:人工智能测试、智能驱动、自动化、测试开发、左移右移与DevOps的持续交付

一、核心概念:路由与请求处理

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 pytestfrom playwright.sync_api import Page
@pytest.fixturedef 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}"))
复制代码



五、性能优化:选择性拦截

避免不必要的处理开销:


# 精确匹配URLpage.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 数据管理建议

  1. 分层管理

  2. 基础 Mock:放置在 conftest.py

  3. 场景 Mock:封装为独立模块

  4. 数据工厂


   def generate_user_data(role="user"):       return {           "name": f"test_{role}",           "permissions": ["read"] if role=="user" else ["read","write"]       }
复制代码


  1. 使用模板引擎


   from jinja2 import Template      template = Template('{"user": "{{ name }}", "role": "{{ role }}"}')   route.fulfill(body=template.render(name="admin", role="superuser"))
复制代码



七、注意事项

  1. 作用域控制

  2. 使用 browser_context.route() 实现上下文隔离

  3. 通过 page.unroute() 及时清理避免污染

  4. 真实请求验证


   # 临时禁用Mock进行验证   with page.expect_request("**/api/data") as req_info:       page.click("#refresh-btn")    request = req_info.value    assert request.post_data == '{"valid":true}'
复制代码


  1. 资源释放


   # 测试结束后移除路由   def teardown():       page.remove_route(handler)
复制代码




最佳实践提示

将核心 Mock 逻辑封装为独立模块,通过环境变量控制 Mock 开关:

if os.getenv("MOCK_MODE") == "enable":
    apply_mocks(page)


通过灵活运用 Playwright 的请求拦截能力,你可以构建出完全可控的测试环境,大幅提升测试用例的稳定性和执行速度。这种技术特别适用于:


  • 微服务架构的集成测试

  • 第三方依赖的异常模拟

  • 前端性能优化验证

  • CI/CD 流水线中的无后端测试


掌握这些技巧,将使你的自动化测试水平进入全新维度!


测试开发全景图:人工智能测试、智能驱动、自动化、测试开发、左移右移与DevOps的持续交付

用户头像

社区:ceshiren.com 微信:ceshiren2023 2022-08-29 加入

微信公众号:霍格沃兹测试开发 提供性能测试、自动化测试、测试开发等资料、实事更新一线互联网大厂测试岗位内推需求,共享测试行业动态及资讯,更可零距离接触众多业内大佬

评论

发布
暂无评论
Playwright进阶篇 (5) | 网络请求拦截与Mock_测吧(北京)科技有限公司_InfoQ写作社区