Playwright快速上手:从零开始掌握UI自动化测试

张开发
2026/4/12 8:58:53 15 分钟阅读

分享文章

Playwright快速上手:从零开始掌握UI自动化测试
1. Playwright是什么为什么选择它做UI自动化测试第一次接触Playwright时我和很多测试工程师一样好奇已经有了Selenium这样的老牌工具为什么还要学新框架直到在电商项目中遇到动态元素加载问题才明白——传统工具在等待机制和浏览器兼容性上的短板会直接导致30%的测试用例不稳定。Playwright是微软开源的现代化UI测试工具它用更智能的设计解决了这些痛点。举个实际例子当页面有个按钮需要3秒后才可点击用Selenium你得手动加sleep(3)而Playwright的自动等待机制会持续检测元素状态真正实现所见即测试。这种设计理念的差异让我们的测试脚本稳定性从70%提升到了98%。与常见工具对比Playwright有三大杀手锏全栈浏览器支持Chromium、Firefox和WebKit三大内核全覆盖特别适合需要Safari兼容性测试的团队多语言生态Python、Java、.NET、Node.js四种官方SDK我用Python版写脚本Node.js版做性能测试零配置等待内置的智能等待会自动判断元素可操作性不用再写一堆time.sleep去年给某金融项目做自动化改造时我们对比了不同框架的测试效率。在同样的登录模块测试中Selenium脚本平均执行时间8.2秒Cypress脚本5.6秒Playwright脚本3.8秒这种性能优势在大型测试套件中会形成复利效应。更惊喜的是它的多页面管理——传统工具切换标签页要操作句柄而Playwright的BrowserContext天然支持多Tab并行就像这样# 创建两个独立上下文相当于两个隐身模式浏览器 context1 browser.new_context() context2 browser.new_context() # 在不同上下文同时操作 page1 context1.new_page() page2 context2.new_page()2. 环境搭建10分钟搞定全家桶新手最容易卡在环境配置上这里分享我优化过的安装流程。先确保Python≥3.7推荐3.8然后三步走2.1 核心组件安装用pip安装时建议加上--pre参数获取最新特性版我习惯用清华源加速pip install --pre playwright -i https://pypi.tuna.tsinghua.edu.cn/simple pip install pytest-playwright # 测试框架集成2.2 浏览器驱动部署运行安装命令时会自动下载三大浏览器约300MB如果网络不稳定可以分段下载playwright install chromium # 先装最常用的 playwright install webkit # 需要Safari测试时再装遇到下载失败时可以手动指定镜像路径公司内网部署时特别有用PLAYWRIGHT_DOWNLOAD_HOSThttps://npmmirror.com/mirrors/ playwright install2.3 IDE配置技巧在VSCode中建议安装两个插件Playwright Test官方插件提供代码提示Browser Preview实时查看测试页面配置launch.json实现调试运行{ version: 0.2.0, configurations: [ { name: Debug Playwright, type: python, request: launch, program: ${file}, args: [--headed] // 非无头模式运行 } ] }3. 录制与定位新手快速产出脚本的秘诀3.1 智能录制实战Playwright CodeGen是我带新人时必教的功能。启动命令后会在浏览器右侧实时生成操作代码playwright codegen https://example.com --target python最近帮团队优化登录脚本时发现几个实用技巧点击Record暂停录制后可以手动调整定位策略右键元素选择Copy selector获取CSS路径按住Shift键可录制鼠标悬停操作录制生成的代码可能需要优化比如这段电商加入购物车脚本# 录制原始版 page.locator(div:nth-child(3) .add-cart).click() # 优化后版本 page.get_by_role(button, name加入购物车).click()3.2 元素定位宝典经过20项目实践我总结出定位策略的黄金法则语义化定位优先# 最佳实践 - 通过ARIA角色定位 page.get_by_role(button, name提交).click() # 次选 - 文本定位 page.get_by_text(立即购买).hover()CSS/XPath定位技巧# 精确匹配属性 page.locator(input[typepassword]).fill(123456) # 包含特定class page.locator(button:has(.icon-cart)).click()列表处理方案# 获取所有商品项 items page.locator(.product-item).all() for item in items[:3]: # 只操作前三个 item.locator(.price).text_content()特殊场景处理方案动态ID元素使用^前缀匹配或XPath的contains()iframe嵌套先用frame_locator定位框架Shadow DOM强制穿透语法4. 核心操作从点击到断言的完整链路4.1 交互操作大全在电商项目中最常使用的三大操作文件上传的三种模式# 单文件 page.locator(input[typefile]).set_input_files(avatar.png) # 多文件 page.locator(input[typefile]).set_input_files([ file1.pdf, file2.jpg ]) # 模拟拖放 page.locator(#drop-area).dispatch_event(drop, { files: [File(report.xlsx)] })鼠标高级操作轨迹模拟page.locator(.slider).hover() page.mouse.down() page.mouse.move(300, 0) # 横向拖动300px page.mouse.up()键盘组合键处理方案# 常规按键 page.keyboard.press(Enter) # 组合键 page.keyboard.press(ControlShiftI) # 输入特殊字符 page.keyboard.type(你好) # 支持直接输入中文4.2 断言机制解析好的断言应该像侦探查案——既要验证表面现象也要检查背后证据。推荐这套组合拳# 元素可见性验证 expect(page.get_by_text(支付成功)).to_be_visible() # 表单值校验 expect(page.locator(#total)).to_have_text(128.00) # 页面级断言 expect(page).to_have_url(https://checkout/complete) # 自定义条件 expect(lambda: page.evaluate(window._appState)).to_pass()复杂断言的最佳实践def test_order_flow(): # 操作流程... # 多重验证 expect(page).to_have_url(contains(order_id)) expect(page.locator(.order-number)).not_to_be_empty() expect(page.get_by_role(heading)).to_contain_text(感谢购买) # 异步数据检查 with page.expect_response(**/api/orders*) as resp: assert resp.value.json()[status] completed5. 高级技巧让脚本更健壮的秘密5.1 异常处理方案在金融系统测试中我总结了这套异常处理模板try: page.click(button:has-text(交易), timeout5000) except Exception as e: # 自动截图并记录DOM timestamp datetime.now().strftime(%Y%m%d_%H%M%S) page.screenshot(pathferror_{timestamp}.png) with open(fdom_{timestamp}.html, w) as f: f.write(page.content()) # 重试逻辑 if is not clickable in str(e): page.wait_for_selector(button:has-text(交易), stateattached)5.2 测试数据管理推荐使用这套数据工厂模式# conftest.py pytest.fixture def user_data(): return { vip_user: {username: viptest.com, credit: 5000}, normal_user: {username: usertest.com, credit: 1000} } # test_checkout.py def test_vip_checkout(page, user_data): user user_data[vip_user] page.fill(#username, user[username]) assert page.locator(#credit).text_content() str(user[credit])5.3 性能优化技巧通过浏览器上下文复用提升50%执行速度def test_multiple_scenarios(): with sync_playwright() as p: browser p.chromium.launch() context browser.new_context() # 场景1 page1 context.new_page() page1.goto(https://example.com/login) # ...操作... # 场景2 - 复用上下文 page2 context.new_page() page2.goto(https://example.com/checkout) context.close()6. 真实项目踩坑记录去年在跨境电商项目中发现一个典型问题支付页面在Chrome正常但在WebKit失败。通过以下步骤定位启用详细日志PLAYWRIGHT_DEBUG1 pytest test_payment.py发现是字体加载超时[WebKit] Loading font from https://cdn.example.com/font.woff timed out解决方案# 方案1禁用字体 context browser.new_context( ignore_https_errorsTrue, bypass_cspTrue ) # 方案2mock字体请求 page.route(**/*.woff, lambda route: route.fulfill(body))另一个常见问题是元素遮挡开发同事在按钮上层加了透明div做埋点。通过这个检查脚本发现问题def is_clickable(locator): return locator.evaluate( el { const rect el.getBoundingClientRect(); const elAtPoint document.elementFromPoint( rect.left rect.width/2, rect.top rect.height/2 ); return el elAtPoint || el.contains(elAtPoint); } )

更多文章