Playwright是由Microsoft开发的现代化端到端(E2E)测试框架,支持Chromium、Firefox、WebKit等主流浏览器,并提供跨语言API(JavaScript/TypeScript、Python、Java、C#)。
它以速度快、稳定性高、异步支持著称,尤其适合复杂Web应用的自动化测试和爬虫开发。以下是从零开始的完整入门指南:
一、为什么选择Playwright?
- 跨浏览器支持:一套API兼容Chromium、Firefox、WebKit,无需额外驱动。
- 自动等待机制:操作元素时自动等待其可交互(如点击、输入),减少“flaky tests”。
- 多语言支持:Python/TypeScript等主流语言均可编写测试脚本。
- 高级调试功能:内置录制器、跟踪回放、网络拦截。
- 并行测试:原生支持并行执行,加速CI/CD流程。
对比Selenium:Playwright基于WebSocket双向通信(非Selenium的HTTP协议),启动更快且无需管理浏览器驱动版本。
二、环境安装(以Python为例)
-
安装Python(≥3.7)并验证:
python --version # 需输出3.7+
-
安装Playwright库:
pip install playwright
-
安装浏览器内核(默认Chromium):
playwright install chromium # 可选firefox/webkit
若需控制已安装的Chrome/Edge,启动时指定路径即可。
三、第一个测试脚本
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
# 启动浏览器(headless=False显示界面)
browser = p.chromium.launch(headless=False)
page = browser.new_page()
# 导航至目标页并断言标题
page.goto("https://example.com")
assert"Example Domain"in page.title()
# 输入搜索词并提交
page.locator("input#kw").fill("通讯")
page.locator("button#go").click()
# 等待结果加载并打印
page.wait_for_timeout(1000) # 简单等待(实际推荐用事件等待)
results = page.locator(".result-item").all()
for item in results:
print(item.inner_text())
browser.close()
关键步骤:
locator()
:定位元素(支持CSS/XPath/Text选择器)。fill()/click()
:自动等待元素可操作后再执行。wait_for_timeout()
:强制等待(仅调试用,正式环境改用事件等待)。
⚠️ 注意:避免使用
time.sleep()
,会破坏Playwright的异步事件机制。
四、核心技巧与功能
元素定位策略:
- 智能选择器:优先用
page.get_by_text("登录")
或page.get_by_role("button")
,更贴近用户视角。 - 链式操作:
page.locator("div.result").locator("a").click()
。
等待优化:
- 事件等待:替代
wait_for_timeout
,用page.wait_for_selector(".loaded")
或page.wait_for_response()
。 - 全局超时设置:通过
BrowserContext
调整默认等待时间:
context = browser.new_context(default_timeout=10000) # 10秒超时
录制生成脚本(快速上手神器):
playwright codegen https://baidu.com -o test.py
操作浏览器界面,自动生成Python脚本(适合基础场景,复杂逻辑需手动优化)。
跟踪调试:
context.tracing.start(snapshots=True, screenshots=True)
# 执行测试操作...
context.tracing.stop(path="trace.zip")
通过playwright show-trace trace.zip
回放完整执行过程,包括网络请求和DOM快照。
五、高级应用场景
模拟登录状态:
注入Cookie避免重复登录:
await context.add_cookies([{
"name": "sessionid",
"value": "xxx",
"domain": ".juejin.cn"
}])
await context.storage_state(path="auth.json") # 保存状态复用
拦截网络请求:
Mock接口响应或修改请求:
page.route("**/api/data", lambda route: route.fulfill(status=200, body="Mock Data"))
多浏览器/设备测试:
- 并行运行Chromium/Firefox/WebKit。
- 模拟移动设备(如Galaxy S5):
from playwright.sync_api import Device
context = browser.new_context(**p.devices["Galaxy S5"])
六、最佳实践
项目结构:
my-project/
├── tests/ # 测试脚本
│ └── search.spec.py
├── playwright.config.py # 配置文件
└── test-results/ # 跟踪/截图等输出
配置示例(playwright.config.py
):
from playwright import define_config
define_config(
headless=True, # 无头模式
retries=1, # 失败自动重试
timeout=30000, # 单测试超时30s
screenshot="only-on-failure" # 失败时截图
)
测试组织:
- 使用
pytest-playwright
管理测试用例。 - 通过
@pytest.mark.parametrize
实现数据驱动测试。
持续集成(CI) :在GitHub Actions中配置Playwright,自动安装依赖及浏览器。
推荐阅读
软件测试/测试开发丨Pytest测试用例生命周期管理-Fixture
软件测试/测试开发丨Python学习笔记之基本数据类型与操作