Playwright 测试生成实战:从 codegen 命令到定位器生成与模拟环境的完整指南
Playwright 内置的测试生成器(Test Generator / Codegen)让你在真实浏览器中操作网页时自动录制并生成可用的测试代码,是快速起步 Web 测试的官方推荐方式。本篇指南覆盖 Playwright 官方文档《Generating tests》(docs/src/codegen-intro.md)的全部核心内容:四种语言下运行 codegen 命令、录制操作与断言、生成定位器(Locator),以及带视口、设备、配色、地理位置、时区模拟和已认证状态复用的生成方式,并结合仓库源码说明 codegen 命令背后的实现链路,帮助你在实际项目中快速搭建可维护的自动化测试基线。
Codegen 是什么:两个窗口的工作模型
Playwright 可以自动生成测试,为快速开始测试提供了一种途径。运行 codegen 后会打开两个窗口:
- 浏览器窗口:用于交互,你在其中的点击、输入等操作会被实时分析;
- Playwright Inspector 窗口:用于录制、复制和管理生成的测试代码。
生成器会分析当前渲染后的页面,为每次交互推荐最优定位器,优先使用 role、text 和 test id 定位器;当多个元素匹配同一个定位器时,生成器会自动改进(细化)定位器,使其能唯一标识目标元素,从而减少测试失败和抖动(flakiness)。
从源码结构看,推荐逻辑由一套与语言绑定的代码生成器实现:packages/isomorphic/codegen/ 目录下分别提供了 javascript.ts、python.ts、csharp.ts、java.ts 等语言生成器,由 languages.ts 统一调度,这也解释了为什么同一套录制操作可以输出多种语言的测试代码。
运行 Codegen:四种语言的启动命令
使用 codegen 命令启动测试生成器,后面跟随你要生成测试的网站 URL。URL 是可选参数——省略后也可以直接在浏览器窗口里输入。
npx playwright codegen demo.playwright.dev/todomvc
mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="codegen demo.playwright.dev/todomvc"
playwright codegen demo.playwright.dev/todomvc
pwsh bin/Debug/net8.0/playwright.ps1 codegen demo.playwright.dev/todomvc
源码视角:codegen 命令支持哪些选项
在 program.ts 中,codegen [url] 命令的定义为:
codegen [url] open page and generate code for user actions
它直接声明了三个专属选项:
| 选项 | 说明 |
|---|---|
-o, --output <file name> |
将生成的脚本保存到文件 |
--target <language> |
指定生成语言,可选值:javascript、playwright-test、python、python-async、python-pytest、csharp、csharp-mstest、csharp-nunit、csharp-xunit、java、java-junit(默认随语言包,Node 环境默认 playwright-test) |
--test-id-attribute <attributeName> |
指定用于生成 data test ID 选择器的属性名 |
此外,codegen 复用了 commandWithOpenOptions(见 program.ts),因此还自带一组通用选项,其中与测试生成最相关的包括:
| 选项 | 说明 |
|---|---|
-b, --browser <browserType> |
选择浏览器:cr/chromium、ff/firefox、wk/webkit,默认 chromium |
--viewport-size <size> |
指定视口像素尺寸,例如 "1280, 720" |
--device <deviceName> |
模拟设备,例如 "iPhone 11"(会同时设置视口尺寸和 user agent 等) |
--color-scheme <scheme> |
模拟首选配色,"light" 或 "dark" |
--geolocation <coordinates> |
指定地理坐标,例如 "37.819722,-122.478611" |
--lang <language> |
指定语言/地区,例如 "en-GB" |
--timezone <time zone> |
模拟时区,例如 "Europe/Rome" |
--user-agent <ua string> |
指定 user agent 字符串 |
--load-storage <filename> / --save-storage <filename> |
加载/保存上下文存储状态(cookies、localStorage、IndexedDB) |
--user-data-dir <directory> |
使用指定用户数据目录代替全新上下文 |
--http-credentials <credentials> |
以 "username:password" 形式提供 HTTP 认证凭据 |
--save-har <filename> / --save-har-glob <glob> |
会话结束时保存 HAR 网络文件,可按 URL glob 过滤 |
--proxy-server <proxy> / --proxy-bypass <bypass> |
指定代理服务器及绕过域 |
--channel <channel> |
Chromium 发行渠道,如 "chrome"、"msedge-dev" |
--timeout <timeout> |
Playwright 操作的超时毫秒数,默认无超时 |
--block-service-workers、--ignore-https-errors |
拦截 Service Worker、忽略 HTTPS 错误 |
调用链路:从 CLI 到 Recorder
在 browserActions.ts 中,codegen() 函数的处理流程可以概括为:
- 通过
launchContext(options, { headless: !!process.env.PWTEST_CLI_HEADLESS, ... })启动浏览器上下文(默认有头模式,仅测试环境PWTEST_CLI_HEADLESS才无头); - 在临时目录创建 trace 存储目录
playwright-recorder-trace-<时间戳>; - 调用
context._enableRecorder({ language, launchOptions, contextOptions, device, saveStorage, mode: 'recording', testIdAttributeName, outputFile })开启录制器,mode为recording; - 若提供了 URL 则
openPage(context, url)打开页面,随后保持进程等待交互。
也就是说,CLI 选项最终会被打包进录制器与上下文的配置中,--target 决定 language,--save-storage 决定 saveStorage,--test-id-attribute 决定 testIdAttributeName,这些参数直接决定了 Inspector 界面行为和生成代码形态。
录制一个测试:操作与断言
运行 codegen 后,在浏览器中执行操作,Playwright 会自动为你的交互生成代码。生成器分析渲染后的页面并推荐最优定位器,优先 role、text 和 test id 定位器;当多个元素匹配时会自动细化定位器以唯一标识目标元素,降低失败率与抖动。
通过测试生成器可以录制:
- 操作(Actions):直接与页面交互即可录制 click、fill 等操作;
- 断言(Assertions):点击工具栏图标后再点击页面元素进行断言,支持三种类型:
assert visibility——断言元素可见;assert text——断言元素包含特定文本;assert value——断言元素具有特定值。
完成页面交互后,按 record 按钮停止录制,再用 copy 按钮把生成的代码复制到你的编辑器。使用 clear 按钮可清空代码重新录制;全部完成后,关闭 Playwright Inspector 窗口或停止终端命令即可。
生成定位器:Pick Locator 工作流
测试生成器同样可以单独用于生成定位器(Locator),步骤如下:
- 按 Record 按钮停止录制,此时 Pick Locator 按钮会出现;
- 点击 Pick Locator 按钮,在浏览器窗口中把鼠标悬停到元素上,可以看到每个元素下方显示的高亮定位器;
- 点击你想定位的元素,对应定位器代码会出现在 Pick Locator 按钮旁的定位器实验场(locator playground)中;
- 在实验场中编辑定位器以微调,同时可以看到匹配元素在浏览器窗口中的高亮变化;
- 用复制按钮拷贝定位器,粘贴到你的代码中。
这一“悬停预览 + 点击确认 + 在线微调”的流程与代码生成共用同一套定位器推荐逻辑(packages/isomorphic/codegen/ 中的生成器实现),因此手动拾取的定位器与自动生成的定位器遵循相同的“role / text / test id 优先、唯一性细化”策略。
模拟环境与已认证状态:为特定场景生成测试
除了默认桌面视口,你还可以针对特定视口、设备、配色方案、地理位置、语言或时区生成测试,测试生成器也能在生成时保持已认证状态。
模拟视口与设备
测试需要在与运行一致的条件下录制,因此 Playwright 打开的是一个固定(非响应式)视口的浏览器窗口:
# 指定视口尺寸
npx playwright codegen --viewport-size="800,600" playwright.dev
# 模拟移动设备(同时设置视口与 user agent 等)
npx playwright codegen --device="iPhone 13" playwright.dev
对应 Java / Python / C# 只需把 npx playwright 换成上文各语言的命令前缀(如 playwright、mvn exec:java ... -D exec.args="codegen ..."、pwsh bin/Debug/net8.0/playwright.ps1)。
模拟配色、地理位置、语言与时区
# 模拟深色模式
npx playwright codegen --color-scheme=dark playwright.dev
# 同时模拟时区、地理位置(罗马坐标)与意大利语,并用地图页验证
npx playwright codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" bing.com/maps
保存与复用已认证状态
--save-storage:会话结束时保存 cookies、localStorage 和 IndexedDB 数据。适合把“登录”这一步单独录制成一次会话:
npx playwright codegen github.com/microsoft/playwright --save-storage=auth.json
完成认证并关闭浏览器后,auth.json 中即包含可复用的 storage state。注意该文件包含敏感信息,文档明确建议仅在本地使用,加入 .gitignore 或用完即删。
--load-storage:消费之前保存的 storage state,恢复 cookies、localStorage 与 IndexedDB,让大多数 Web 应用直接进入登录态,从而继续从已登录状态生成测试:
npx playwright codegen --load-storage=auth.json github.com/microsoft/playwright
--user-data-dir:为浏览器会话设置固定用户数据目录,复用已有浏览器配置中的认证状态。需要留意的是(原文档中的 warning):自 Chrome 136 起,默认用户数据目录无法被 Playwright 等自动化工具访问,你必须为测试单独创建一个用户数据目录:
npx playwright codegen --user-data-dir=/path/to/your/browser/data/ github.com/microsoft/playwright
--http-credentials:以 HTTP Basic 认证方式录制,凭据形式为"username:password"。与内嵌在 URL 中的凭据不同,它会被发送到录制会话中请求凭据的任意源,并被包含进生成的代码:
npx playwright codegen --http-credentials="username:password" example.com
非标准场景:用 page.pause() 打开录制器
如果你需要在非标准环境(例如使用 context.route 拦截请求)下使用 codegen,可以在测试脚本中调用 page.pause(),它会打开一个独立的窗口提供 codegen 控件。以 Node.js 为例(Java / Python / C# 写法见 codegen.md 的“Record using custom setup”章节):
const { chromium } = require('@playwright/test');
(async () => {
// Make sure to run headed.
const browser = await chromium.launch({ headless: false });
// Setup context however you like.
const context = await browser.newContext({ /* pass any options */ });
await context.route('**/*', route => route.continue());
// Pause the page, and start recording manually.
const page = await context.newPage();
await page.pause();
})();
这个入口让录制器与任意自定义上下文配置组合,是 --user-data-dir、--save-storage 等 CLI 选项覆盖不到的“逃生通道”:只要保证有头模式(headless: false)即可。
延伸阅读
- 完整的测试生成器指南(含 VS Code 内生成、全部模拟选项与自定义配置):codegen.md
- 定位器(Locator)体系:locators.md
- 录制完成后查看测试轨迹:trace-viewer-intro.md
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00

