---
title: "Playwright Codegen 最佳实践"
language: "zh"
url: "https://docs.testany.io/zh/docs/playwright-codegen-best-practice/"
markdown_url: "https://docs.testany.io/zh/docs/playwright-codegen-best-practice.md"
translation: "https://docs.testany.io/en/docs/playwright-codegen-best-practice.md"
last_updated: "2026-04-21T15:45:20+08:00"
---

# Playwright Codegen 最佳实践

## 1. 概览

本指南将带你使用 Playwright 内置的录制器（codegen），轻松捕捉你的第一个端到端测试——无需繁重的脚本编写。你将学会：

1. 准备本地环境。
2. 启动录制器，并可视化地与目标应用交互。
3. 自动生成基础测试脚本，随着你的点击和输入实时记录。
4. 保存并运行 录制好的脚本，仅需一条命令。
5. 对脚本做最小限度的编辑。

完成后，你将能够自信地录制、微调并执行轻量级的 Playwright 测试，而无需深入编写代码，为日后学习更高级功能打下坚实基础。更多关于 Playwright 的内容，请查看官方文档：[playwright.dev](https://playwright.dev) 。

## 2. **前提条件**

### **2.1 搭建环境**

#### **2.1.1 创建本地目录**

打开文件管理器（Windows Explorer / macOS Finder），在您指定的路径（如桌面、文档等）新建文件夹，命名为 `playwright`。

该目录将作为 Playwright 项目的根目录，用于后续安装和脚本存放。

#### **2.1.2 安装 Node.js**

前往 <https://nodejs.org> 下载 LTS 安装包，双击安装。

#### 2.1.3 切换到 Playwright 目录

用终端或 VS Code 集成终端切换到2.1.1创建的 Playwright 的目录

1. 无 IDE：打开系统终端（Terminal/命令提示符）输入命令。
2. 有 IDE：在 VS Code 底部打开集成终端执行。

```text
cd Playwright文件夹绝对路径
```

#### 2.1.4 安装 Playwright

1. 下载并执行初始化脚本

   ```bash
   npm init playwright@latest
   ```
2. 选择语言（`JavaScript` / `TypeScript`），用↑↓键选择后按回车

   ```text
   Do you want to use TypeScript or JavaScript? _
     › TypeScript
       JavaScript
   ```
3. 选择测试目录：默认 `tests`，也可改成 `e2e` 或其他文件名等

   ```text
   Where to put your end-to-end tests? › tests
   ```
4. 是否添加 GitHub Actions Workflow

   ```text
   Add a GitHub Actions workflow? (y/N) › false
   ```

   1. `Y`：在 .github/workflows/playwright.yml 下生成一个 CI 配置，让您 push 到 GitHub 后自动在 GitHub Actions 上运行 Playwright 测试、生成报告和上传视频/截图。
   2. `N`：跳过，需要自行配置 CI。
5. 安装 Playwright 浏览器（必须选 `true`，可直接回车）

   ```text
   Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) › true
   ```

完成提示

```text
Happy Hacking!
```

脚本会自动：

- 更新或创建 package.json（添加依赖、测试脚本命令）
- 生成 `playwright.config.js`/ `.ts`
- 创建测试目录和示例文件
- 生成 GitHub Actions 配置（如果选了）

### 2.2 配置 Playwright

要在 Playwright 中获得录屏→回放→调试的最佳体验，建议您根据个人需求选择以下 `playwright.config.js` 的关键配置来开启截图（screenshot）、操作轨迹（trace）和视频录制（video）。

- 第16行：设置超时时间为30s
- 第34行：设置每次执行都收集 trace
- 第35行：设置每次执行都生成视频
- 第41-74行：选择在哪些浏览器上并行测试

```javascript
// @ts-check
import { defineConfig, devices } from '@playwright/test';

/**
 * Read environment variables from file.
 * https://github.com/motdotla/dotenv
 */
// import dotenv from 'dotenv';
// import path from 'path';
// dotenv.config({ path: path.resolve(__dirname, '.env') });

/**
 * @see https://playwright.dev/docs/test-configuration
 */
export default defineConfig({
  timeout: 30 * 1000,
  testDir: './tests',
  /* Run tests in files in parallel */
  fullyParallel: true,
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: !!process.env.CI,
  /* Retry on CI only */
  retries: process.env.CI ? 1 : 0,
  /* Opt out of parallel tests on CI. */
  workers: process.env.CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: 'html',
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Base URL to use in actions like `await page.goto('/')`. */
    // baseURL: 'http://127.0.0.1:3000',

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on',
    video: 'on',
    // headless: false,
  },

  /* Configure projects for major browsers */
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },

    // {
    //   name: 'firefox',
    //   use: { ...devices['Desktop Firefox'] },
    // },

    // {
    //   name: 'webkit',
    //   use: { ...devices['Desktop Safari'] },
    // },

    /* Test against mobile viewports. */
    // {
    //   name: 'Mobile Chrome',
    //   use: { ...devices['Pixel 5'] },
    // },
    // {
    //   name: 'Mobile Safari',
    //   use: { ...devices['iPhone 12'] },
    // },

    /* Test against branded browsers. */
    // {
    //   name: 'Microsoft Edge',
    //   use: { ...devices['Desktop Edge'], channel: 'msedge' },
    // },
    // {
    //   name: 'Google Chrome',
    //   use: { ...devices['Desktop Chrome'], channel: 'chrome' },
    // },
  ],

  /* Run your local dev server before starting the tests */
  // webServer: {
  //   command: 'npm run start',
  //   url: 'http://127.0.0.1:3000',
  //   reuseExistingServer: !process.env.CI,
  // },
});
```

对于截图与视频录制，您还可以考虑以下方案。它可以既节省存储、也能针对失败用例快速定位。

```javascript
screenshot: 'only-on-failure',     // 失败用例才截图
video: 'retain-on-failure',        // 失败用例才录屏
trace: 'on-first-retry',           // 首次重试时收集 trace
```

### **2.3 安装 VS Code & Playwright 插件（可选，仅修改脚本时需）**

- 按照 VS Code 官方安装指南完成下载与安装：<https://code.visualstudio.com/docs/setup/setup-overview>。
- 启动 VS Code，点击“扩展”图标，搜索 ”Playwright Test for VSCode“ 并安装。
- 打开第 1 步创建的 playwright 文件夹：**File → Open Folder… → playwright** 。

### **2.4 了解 Playwright Codegen 的优势与局限**

**优势**：

一键录制、自动生成 getByRole/getByText 定位、可视化回放、跨浏览器云端执行。

**局限**：

录制器主要记录**页面内简单直观的操作**（点击、输入文本等）。对于需要额外编排或无法通过浏览器事件直接获知的操作，录制器无从自动生成有效代码。测试人员需要基于Playwright提供的API手动编写这些步骤，以实现完整的用户场景。

1. **滚动 & 延时**：录制器不会捕获页面滚动、页面缩放、等待类操作，需要在生成脚本里用“插入片段”或复制示例代码来补充。
2. **定位精度**：录制器有时会生成宽泛选择器（如顶层 #root），建议在 Inspector 中右键替换为更语义化的定位器（getByRole／getByText）。
3. **自定义交互类操作**：当操作涉及**悬停 (Hover)、拖拽 (Drag and Drop)、右键/上下文菜单、文件上传/下载、浏览器对话框、其他特殊交互**（包括键盘组合键、窗口切换、新标签页打开等）时，录制器无法自动生成有效代码。

## 3. 分步指引

### 3.1 **录制脚本**

#### 3.1.1 启动录制

在系统自带终端运行以下命令，或在 VS Code 左侧 “Testing” 面板，点击“Record Playwright Script”按钮。

```bash
npx playwright codegen
```

此操作会自动打开：

- **浏览器窗口**：在这里进行点击、输入、导航等操作。

  ![image-20250422-074924.png](https://docs.testany.io/docs/images/zh/image-20250422-074924_d575d0a7.png)
- **Inspector 窗口**：工具栏＋实时生成的脚本。

  ![image-20250422-075021.png](https://docs.testany.io/docs/images/zh/image-20250422-075021_42608625.png)

#### 3.1.2 执行业务流程

在打开的浏览器中执行业务流程。

🔴 **Record / Stop（录制/停止）**

- 作用：校验目标元素已在页面中渲染并且对用户可见（非隐藏、非遮挡、非透明）。
- 操作：选择该工具后，在浏览器里执行操作。

**Pick Locator**（选择定位器）

- 作用：显示推荐的 Playwright 定位器。
- 操作：选择该工具后，点击浏览器里任何元素会在 Inspector 的 “Locator” 窗口显示推荐的 Playwright 定位器。

![image-20250422-083133.png](https://docs.testany.io/docs/images/zh/image-20250422-083133_cc93df66.png)

**Assert Visibility（断言可见性）**

- 作用：校验目标元素已在页面中渲染并且对用户可见（非隐藏、非遮挡、非透明）。
- 操作：选择该工具后，在浏览器里点某个元素。
- 生成代码示例：

```javascript
await expect(page.locator('button#submit')).toBeVisible();
```

**Assert Text（断言文本内容）**

- 作用：校验任意元素（<div>、<span>、<li>、<h1> 等）的 可见文本 与预期字符串是否一致。
- 底层原理：读取元素的 innerText（渲染后文本），自动去掉多余空白后进行精确或正则匹配。
- 生成代码示例：

```javascript
await expect(page.locator('h1.page-title')).toHaveText('欢迎使用 MyApp');
```

**Assert Value（断言表单值）**

- 作用：校验表单控件（<input>、<textarea>、<select> 等）的 value 属性是否与预期一致。
- 底层原理：直接读取并比较元素的 .value 属性，而不是其文本节点。
- 生成代码示例：

```javascript
await expect(page.getByRole('textbox', { name: '邮箱' })).toHaveValue('example@example.com');
```

**Assert Snapshot（断言 ARIA 语义快照）**

- 作用：对比元素在可访问性树（Accessibility Tree）里的语义和文本结构是否与预期一致（非图片对比）。
- 底层原理：捕获元素及其子树在浏览器内核里的 **Accessibility Tree** 表示，包括每个节点的角色 (heading、paragraph、button 等)、名称（对用户可见的文字）、层级信息（如 heading 的 level）等。将这棵树“扁平化”为一段 YAML‐风格的文本，用来做可访问性回归测试或内容结构校验。
- 生成代码示例：

```javascript
await expect(page.locator('#comp-lp6ttrri')).toMatchAriaSnapshot(`
  - heading "Rapid Fault Detection" [level=3]
  - paragraph: Advanced capabilities for quick identification and pinpointing of issues, minimizing downtime and enhancing software reliability.
  - paragraph
  - heading "Seamless DevOps Integration" [level=3]
  - paragraph: Effortlessly integrates with existing DevOps tools, providing insightful analytics and secure testing, all within a streamlined workflow.
  - paragraph
  - heading "Streamlined Automation" [level=3]
  - paragraph: Automates repetitive testing tasks, enabling continuous and efficient testing throughout the DevOps cycle.
  - paragraph
  - heading "Comprehensive Testing Environments" [level=3]
  - paragraph: Supports multi-environment testing, including complex user journey simulations, ensuring thorough software validation.
`);
```

#### 3.1.3 保存脚本

业务流程执行完后，保存脚本

- **有 IDE**：Inspector 工具栏点击“Stop Recording”，脚本自动载入 VS Code 编辑器。

  ![image-20250422-065022.png](https://docs.testany.io/docs/images/zh/image-20250422-065022_04cdfa91.png)
- **无 IDE**：Inspector 工具栏点击“Copy script”，然后在任意文本编辑器中新建 \*.spec.js 粘贴并保存至 `playwright/tests` 文件夹下。

  ![image-20250422-065045.png](https://docs.testany.io/docs/images/zh/image-20250422-065045_2e3edb71.png)


> **说明**
>
> 如果您不小心误操作，可通过”Clear”按钮清除最近一次误操作的脚本。


![image-20250422-065354.png](https://docs.testany.io/docs/images/zh/image-20250422-065354_d6d06760.png)

### 3.2 **补充脚本（可选）**

Playwright codegen 工具在记录基础操作时非常有效，但对于一些特殊操作，无法自动录制或录制效果不理想，需要后期手动补充。以下分类列出部分常见的无法被录制器被准确捕捉的操作，并提供示例。

#### 3.2.1 **滚动页面操作**

```javascript
// 手动添加页面往下滑 500px
await page.mouse.wheel(0, 500);
```

#### 3.2.2 **显式等待**

```javascript
// 等待按钮出现再点击
await page.waitForSelector('button:has-text("提交")');
await page.click('button:has-text("提交")');
```

#### 3.2.3 **等待网络响应**

```javascript
await page.click('button:has-text("搜索")');
await page.waitForResponse(resp =>
  resp.url().includes('/api/search') && resp.status() === 200
);
```

#### **3.2.4 渲源 hover 手动交互**

```javascript
await page.locator('.menu-button').hover();
await page.click('.menu-item:has-text("设置")');
```

#### **3.2.5 拖拽**

```javascript
await page.locator('#source').dragTo(page.locator('#target'));
```

#### **3.2.6 文件上传**

```javascript
await page.setInputFiles('input[type="file"]', 'tests/assets/example.png');
```

#### **3.2.7 窗口/标签页切换**

```javascript
const [newPage] = await Promise.all([
  page.waitForEvent('popup'),
  page.click('a[target="_blank"]'),
]);
await newPage.waitForLoadState();
await expect(newPage).toHaveURL(/dashboard/);
```

#### **3.2.8 下载/对话框**

```javascript
// 处理 alert
page.on('dialog', async dialog => {
  expect(dialog.message()).toContain('Are you sure');
  await dialog.accept();
});

await page.click('button:has-text("删除")');

// 处理文件下载
const [ download ] = await Promise.all([
  page.waitForEvent('download'),
  page.click('button:has-text("下载")'),
]);
const path = await download.path();
```

> 声明：上述列举的操作类型和示例基于 Playwright 官方文档、社区评论和实际用户反馈综合考虑，目的是为初学者和自动化测试工程师提供一个明确可扩展的指南。其中列举的示例不必然适用于所有项目，请根据自己的场景选择合适的解决方案。

### **3.3 执行和回放脚本**

在系统自带终端运行以下命令。

```bash
npx playwright test --ui
```

Playwright 会在本地启动一个图形化的 **Test Runner UI** 窗口。

![image-20250422-085748.png](https://docs.testany.io/docs/images/zh/image-20250422-085748_9eb866cc.png)

#### **3.3.1 一键运行 & 单测执行**

- **Run（▶）按钮**：

  - 文件级的 ▶：运行整个文件内所有测试
  - 用例级的 ▶：只运行该条测试
- **Run All Tests 按钮**：在窗口顶部或侧边栏可一键启动所有测试的并行执行。

#### **3.3.2 实时日志输出**

- **右侧主面板**：显示当前测试的执行日志、断言结果、控制台输出（`console.log`）等。
- **滚动定位**：当您点击某个测试或用例，它会自动跳到对应的日志和错误堆栈。

#### **3.3.3 可视化回放**

- **操作时间线**：如果您在配置里启用了 `trace: 'on'` 或者测试失败时保留 trace，您可以看到操作时间线。
- **逐步回放**：Trace Viewer 会按时间线展示每一步操作对应的 DOM 快照、网络请求、截图等信息。

更多关于 Trace Viewer 的介绍，请查阅 [Playwright Trace viewer 官方文档](https://playwright.dev/docs/trace-viewer)。

×

## 本页术语

- [环境 (Environment)](https://docs.testany.io/zh/docs/glossary.md#environment)
- [测试脚本 (Test Script)](https://docs.testany.io/zh/docs/glossary.md#test-script)
- [命令 (Command)](https://docs.testany.io/zh/docs/glossary.md#command)
- [执行 (Execution)](https://docs.testany.io/zh/docs/glossary.md#execution)
- [路径（Path）](https://docs.testany.io/zh/docs/glossary.md#path)
- [用户 (User)](https://docs.testany.io/zh/docs/glossary.md#user)
- [断言 (Assertion)](https://docs.testany.io/zh/docs/glossary.md#assertion)
