)
别再傻等接口了用Playwright的Route拦截5分钟搞定Mock数据Python版前端开发中最令人抓狂的瞬间莫过于后端接口还没准备好而你的页面逻辑已经写了一半。我曾经在一个电商项目里因为支付接口延迟交付整个团队被迫停滞了两周。直到发现了Playwright的Route拦截功能——原来我们完全可以在浏览器层面模拟任意接口响应从此告别被动等待。1. 为什么你需要掌握Route拦截技术想象这样一个场景凌晨两点你正在赶制一个紧急需求前端页面需要展示用户订单列表。但后端同事早已下班接口返回的依然是{error: under maintenance}。传统做法可能是手动修改本地JSON文件或者启动一个Mock服务器但这些方案要么太原始要么太重。Playwright的Route拦截提供了第三种可能——直接在浏览器层面劫持特定请求。这意味着无需后端配合独立完成全流程开发模拟网络延迟、错误状态等真实场景快速验证前端异常处理逻辑实现自动化测试中的复杂用例构造# 典型使用场景示例 from playwright.sync_api import sync_playwright def mock_user_api(route, request): if request.url.endswith(/api/user/profile): route.fulfill( status200, json{name: 测试用户, vip: True}, headers{Content-Type: application/json} ) with sync_playwright() as p: browser p.chromium.launch() page browser.new_page() page.route(**/api/user/*, mock_user_api) page.goto(https://your-app.com/profile) # 页面将收到我们预设的模拟数据2. 五分钟快速上手基础拦截实战2.1 安装与环境准备确保已安装Python 3.7和最新版Playwrightpip install playwright playwright install2.2 三种核心拦截模式对比方法适用场景示例场景执行效率continue()仅监控不修改性能指标采集最高fulfill()完全模拟响应开发环境Mock数据高abort()阻断特定请求屏蔽广告追踪脚本中2.3 第一个拦截实例替换用户数据假设我们需要模拟用户VIP状态def mock_vip_user(route): route.fulfill( status200, json{level: diamond, expires: 2099-01-01}, headers{Cache-Control: no-store} ) page.route(**/api/membership, mock_vip_user)提示在开发过程中可以将这些拦截规则保存为独立模块通过环境变量控制是否启用Mock3. 高级应用技巧应对复杂场景3.1 动态响应生成当需要根据请求参数返回不同数据时def dynamic_response(route, request): search_params dict(parse_qs(urlparse(request.url).query)) user_id search_params.get(uid, [])[0] route.fulfill( json{id: user_id, avatar: fhttps://avatar.com/{user_id}.jpg} ) page.route(**/api/user?*, dynamic_response)3.2 混合使用拦截策略有时我们需要组合多种拦截方式def hybrid_interception(route, request): if analytics in request.url: route.abort() # 屏蔽分析请求 elif request.method POST: route.continue_() # 放行所有POST请求 else: # 修改GET请求头 headers {**request.headers, X-Mock: true} route.continue_(headersheaders)3.3 文件与二进制响应模拟处理图片等二进制数据时def mock_image(route): with open(mock-avatar.png, rb) as f: route.fulfill( status200, bodyf.read(), headers{Content-Type: image/png} ) page.route(**/uploads/*.png, mock_image)4. 工程化实践将Mock融入开发流程4.1 配置文件管理建议创建mock_responses.py模块集中管理# mock_responses.py MOCK_CONFIG { /api/login: { status: 401, json: {error: invalid_credentials}, enable: False }, /api/products: lambda: { items: [{id: i, name: f商品{i}} for i in range(1,6)] } } def apply_mocks(page): for path, config in MOCK_CONFIG.items(): if not config.get(enable, True): continue def handler(route): response config() if callable(config) else config route.fulfill(**response) page.route(f**{path}, handler)4.2 与自动化测试结合在Pytest中使用夹具pytest.fixture def mock_page(): with sync_playwright() as p: browser p.chromium.launch() page browser.new_page() apply_mocks(page) # 应用预设的Mock规则 yield page browser.close() def test_checkout_flow(mock_page): mock_page.goto(/checkout) # 断言会收到我们预设的模拟订单数据4.3 性能优化建议对频繁拦截的路径使用正则匹配page.route(re.compile(r/api/v\d/products))避免在拦截器中进行复杂计算必要时使用route.fetch()获取原始响应后再修改async def modify_response(route): response await route.fetch() # 获取原始响应 data await response.json() data[modified] True await route.fulfill(responseresponse, jsondata) page.route(**/api/data, modify_response)5. 常见问题与调试技巧5.1 拦截失效的排查步骤确认URL模式匹配正确建议先用console.log输出请求URL检查是否在其他地方调用了route.continue_()验证拦截器是否注册在页面导航之前5.2 复杂匹配场景示例# 同时匹配多个条件 def complex_matcher(route, request): if (request.method GET and /api in request.url and auth in request.headers): print(f拦截认证请求: {request.url}) route.fulfill(json{token: mock_token}) page.route(**/*, complex_matcher)5.3 调试输出建议在拦截器中添加诊断日志def debug_interceptor(route, request): print(f → 拦截到请求: URL: {request.url} Method: {request.method} Headers: {request.headers} PostData: {request.post_data} ) route.continue_() page.route(**/*, debug_interceptor)在实际项目中我发现最实用的技巧是为不同的测试环境创建不同的Mock预设。比如在staging环境模拟网络延迟在development环境返回极端测试数据。一个精心设计的Mock系统可以帮团队节省数百小时的等待时间。