如何使用 Codegen 来写代码

coding入门9 分钟阅读2026/7/3

我正盯着一个空荡荡的测试文件,对接下来的工作感到头疼。我们团队刚上线了一个包含七个步骤的新用户引导流程,里面有一堆表单验证,而且只有全部走完才能看到控制台。手动测一遍得花 45 分钟,而我们恨不得昨天就把端到端自动化测试写好。问题来了?要从头给这些流程写 Playwright 测试,感觉得花上一个星期。

就在这时,我决定好好试试 Playwright 的 Codegen。之前我也简单折腾过,但从来没真正把它完整融入工作流。下面是我在用它给整个引导流程生成测试时的经验总结——包括它帮我省了哪些力气,又在哪里白瞎了我的时间。

Codegen 到底是个啥

Playwright 的 Codegen 是一个测试录制工具,它会看着你在浏览器里操作,然后实时写出 Playwright 测试代码。它会打开两个窗口:一个是你执行操作的浏览器,另一个是实时显示生成代码的 Playwright Inspector 面板。

它不是那种无代码工具。你依然得懂 Playwright,而且得自己清理生成的代码。不过,如果你想快速搭出测试的骨架——尤其是那种复杂的多步骤流程——它确实贼好用。

上手入门

基础命令非常简单:

npx playwright codegen https://myapp.com/onboarding

这会打开一个浏览器窗口指向你的 URL,旁边并排打开 Inspector 面板。如果你不指定 URL,它会打开一个空白浏览器,让你自己手动导航。

在我的场景下,我想连上我们的预发布环境,并生成 TypeScript 代码:

npx playwright codegen --target=typescript https://staging.myapp.com/onboarding

你也可以指定浏览器:

npx playwright codegen --browser=webkit https://staging.myapp.com/onboarding

--target 参数支持 javascript、playwright-test、python、python-async、csharp 和 java。我一直用 playwright-test,因为那是我们的测试运行器。

录制引导流程

打开 Codegen 后,我把整个引导流程走了一遍。我填了用户名,选了套餐,输入了支付信息,确认了邮箱,最后进入了控制台。

在我点击和输入的同时,Codegen 实时生成了代码。这是前几步生成的代码:

import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {
  await page.goto('https://staging.myapp.com/onboarding');
  await page.getByLabel('Full Name').fill('Alex Rivera');
  await page.getByLabel('Email').fill('alex@test.com');
  await page.getByRole('button', { name: 'Continue' }).click();
  await page.getByLabel('Company Size').selectOption('11-50');
  await page.getByRole('button', { name: 'Next Step' }).click();
  // ... 后面七个步骤以此类推
});

这已经省了大把时间了。要是手动敲这些定位器和交互代码,估计得花好几个小时。不过,原始输出还不能直接上生产环境——这个下面再说。

智能定位器生成

这点真的让我惊艳。Codegen 不是无脑抓取 CSS 选择器或 XPath。它会分析页面,并按照以下优先级挑选最稳健的定位器:

  1. 角色定位器 (getByRole) — 对无障碍访问和稳健性最好
  2. 文本定位器 (getByText) — 适合按钮和链接
  3. 测试 ID 定位器 (getByTestId) — 当你能控制代码时非常好用
  4. 标签定位器 (getByLabel) — 表单字段的绝配
  5. CSS/XPath — 迫不得已才用

当我点击“Continue”按钮时,Codegen 生成了 getByRole('button', { name: 'Continue' }),而不是像 page.locator('#btn-step-1-continue') 这种脆弱的写法。这非常关键,因为基于角色的定位器在面对页面重构时,比 CSS 选择器抗造得多。

当多个元素匹配同一个定位器时——比如我们有次页面上同时出现了两个“Continue”按钮——Codegen 会优化定位器,精准锁定目标。它会加上额外的上下文,比如所属的区块标题或父容器。

添加断言

这个功能我一开始给忽略了。Codegen 不仅能录制操作——还能录制断言。

在 Inspector 的工具栏里有个断言图标。点一下,再去点页面上的元素。你会看到三个选项:

  • 断言可见性 — 验证元素是否可见
  • 断言文本 — 验证元素是否包含特定文本
  • 断言值 — 验证表单元素是否具有特定值

我用这个功能来断言引导流程结束后控制台是否正确加载:

await expect(page.getByRole('heading', { name: 'Welcome to Your Dashboard' })).toBeVisible();
await expect(page.getByText('Setup Complete')).toBeVisible();

这些断言一针见血。我完全不用事后回头再手动去加。

不录制也能挑选定位器

这是我中途发现的一个小技巧:你可以只用 Codegen 来挑选定位器,而不用录制完整的测试。

  1. 点击 Record 按钮暂停录制
  2. 此时会出现 Pick Locator 按钮
  3. 点击它,然后把鼠标悬停在元素上,就能看到推荐的定位器了

当我在调试已有的测试,需要给某个元素找合适的定位器时,这招简直太好用了。我再也不用去猜选择器了,直接打开 Codegen,挑好定位器,复制粘贴到我的测试里就行。

清理代码

说点实在的——Codegen 生成的代码在变成生产代码之前,必须得清理。以下是我要修改的地方:

1. 所有东西都塞进了一个巨大的测试里。 Codegen 录制的是一个连续的流程。我把它拆分成了逻辑独立的测试用例:“能完成步骤 1”、“能选择套餐”、“能进入控制台”。

2. 测试数据是硬编码的。 录制时我输入的每个值在代码里都变成了字面量。我把它们替换成了变量和 fixtures:

// 替换前(Codegen 原始输出)
await page.getByLabel('Full Name').fill('Alex Rivera');

// 替换后(使用测试数据)
await page.getByLabel('Full Name').fill(testUser.fullName);

3. 没有合理的等待策略。 页面加载慢的时候,Codegen 有时会加上 waitForTimeout 调用。这非常脆弱。我把它们换成了更靠谱的 waitForSelectorwaitForURL

4. 多余的交互。 我发现 Codegen 录制了一些我并非有意为之的悬停操作——只是鼠标移动时刚好划过了某些元素。我把这些都删了。

5. 测试名永远叫 "test"。 这毫无参考价值。记得重命名成有描述性的名字。

为现有测试生成定位器

有个工作流比我预想的还好用:把 Codegen 和手写测试结合起来。我会自己写测试结构——describe 块、beforeEach 钩子、测试组织——但只用 Codegen 来生成定位器。

打开它,挑个定位器,粘贴进去。这大概帮我省了 70% 找定位器的时间。再也不用在 DevTools 里审查元素、复制 CSS 选择器,然后祈祷它别挂了。

实用小贴士

  • 在目标环境中录制。 对着 localhost 录制,然后对着预发布环境跑,往往会产生不同的定位器和流程。
  • 慢点录,稳点录。 不小心的点击和悬停会在输出中产生垃圾代码。别急,慢慢来。
  • 多用 Clear 按钮。 如果录制搞砸了,直接在 Inspector 里点 Clear 重来。这比去改一堆烂代码快多了。
  • 先暂停录制,再去挑定位器。 Pick Locator 模式只在录制暂停时才会出现。
  • 立刻复制代码。 Inspector 不会保存状态。一旦关闭,代码就没了。每次录制成功后,赶紧复制到你的编辑器里。
  • 在你的应用里加上 data-testid 属性。 只要有这个属性,Codegen 就会优先使用它,而且从长远来看,这是最稳定的定位器策略。

实话实说

Codegen 并不能替代你对 Playwright 的理解。生成的测试只是个起点,不是最终成品。如果你把输出直接当生产代码用,不清理的话,最终只会得到一堆在 CI 里疯狂报错的脆弱测试。

话虽如此,就我写引导流程这活儿来说,Codegen 把原本可能要花一星期从头写测试的时间,缩短到了大约一天半——录制花了一小时,剩下的时间都在清理和重构。光是生成定位器这一项就省了巨多时间,而断言录制算是个意外之喜,现在也成了我的常规操作。

Codegen 的短板在于:包含大量异步内容的高动态页面、基于 Canvas 的交互,以及任何需要复杂前置状态的场景。遇到这些情况,你还是得老老实实手写测试。

它的最佳使用场景是多步骤表单流程、导航序列,以及任何你需要快速捕捉主流程的 UI。录下来,清理一下,把数据参数化,你就能在极短的时间内得到一个靠谱的测试。

相关 Agent

C

光标编辑器

AI驱动的代码编辑器,支持智能补全和对话。

了解更多 →