<!-- title: Claude Code E2E测试：Playwright MCP到自愈测试 -->

# Claude Code E2E测试全实战：Playwright MCP到自愈测试流水线

**学习目标**：掌握 Claude Code + Playwright MCP Server 的端到端测试全链路——从环境搭建、无障碍快照交互、Page Object Model 架构设计，到三大 Test Agent（Planner/Generator/Healer）驱动的自愈测试流水线。学完即可在真实项目中落地 AI 驱动的 E2E 测试体系。

**适用人群**：有基础 TypeScript/JavaScript 经验、正在使用 Claude Code 进行前端开发的工程师；QA 自动化工程师希望引入 AI 辅助测试流程的团队。

**前置条件**：
- Node.js ≥ 18，已安装 Claude Code CLI
- 一个可本地运行的前端项目（React/Vue/Svelte 均可）
- 基本的 CSS 选择器和 DOM 概念

---

## 一、为什么 Claude Code + Playwright 是 2026 年 E2E 测试最优解

传统 E2E 测试的痛点可以概括为三个字：**慢、脆、贵**。一条测试用例平均编写时间 30 分钟，UI 变动导致 40% 的选择器失效，维护成本占整个测试团队 60% 以上精力。

Claude Code 通过 Playwright MCP Server 拿到了"眼睛"和"手"——它能实时查看页面 DOM 结构（通过无障碍快照而非截图），精准点击元素，填写表单，断言结果。这意味着：

| 传统方式 | Claude Code + Playwright |
|---------|--------------------------|
| 手写选择器，UI 变动就断 | AI 通过无障碍树定位，天然抗变动 |
| 人工设计测试用例 | Planner Agent 自动规划覆盖路径 |
| 断了手动修 | Healer Agent 自动修复选择器 |
| 测试与开发割裂 | 开发者一条命令完成自测闭环 |

```mermaid
flowchart LR
    A[开发者提交代码] --> B[Claude Code 启动 Playwright MCP]
    B --> C{Planner Agent<br/>规划测试路径}
    C --> D[Generator Agent<br/>生成测试代码]
    D --> E[Healer Agent<br/>修复失败用例]
    E --> F[测试报告]
    F -->|通过| G[合并代码]
    F -->|失败| E
```

---

## 二、环境搭建：5 分钟从零到浏览器可控

### 2.1 安装 Playwright

```bash
# 在项目根目录
npm init -y
npm install -D @playwright/test
npx playwright install chromium
```

### 2.2 配置 Playwright MCP Server

Playwright MCP 是微软官方维护的 MCP 服务器，它将 Playwright 的浏览器自动化能力暴露为 MCP 工具，供 Claude Code 直接调用。

在项目根目录创建 `.mcp.json`（或写入 `~/.claude/.mcp.json` 全局生效）：

```json
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest"
      ]
    }
  }
}
```

如果你需要浏览器可见模式（调试时推荐），加入 `--headed` 参数：

```json
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest",
        "--headed"
      ]
    }
  }
}
```

### 2.3 核心配置选项

Playwright MCP 支持以下关键配置参数：

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `--browser` | 浏览器类型：`chromium`/`firefox`/`webkit` | `chromium` |
| `--headed` | 有头模式，可看到浏览器窗口 | `false`（headless） |
| `--vision` | 启用视觉模式（截图代替无障碍快照） | `false` |
| `--viewport-size` | 视口大小，格式 `width,height` | `1280,720` |
| `--user-data-dir` | 用户数据目录（保持登录态） | 临时目录 |

一个面向 CI 的生产级配置：

```json
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest",
        "--browser", "chromium",
        "--viewport-size", "1440,900"
      ]
    }
  }
}
```

### 2.4 验证安装

启动 Claude Code 后输入：

```
> 请启动浏览器并访问 https://example.com，告诉我页面标题
```

Claude Code 会调用 `browser_navigate` 工具打开页面，然后调用 `browser_snapshot` 获取无障碍树来读取标题。如果看到类似以下输出，说明 MCP 连接成功：

```
浏览器已启动，页面标题为 "Example Domain"
页面包含一个标题 "Example Domain" 和一段说明文字
```

### 2.5 常见问题

**问题 1：`npx @playwright/mcp` 报错找不到包**

```bash
# 确认 Playwright MCP 包存在
npm view @playwright/mcp version
# 如果不存在，使用完整路径
npx -y @playwright/mcp@latest
```

**问题 2：headless 模式下页面渲染异常**

添加环境变量强制 GPU 渲染：

```json
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"],
      "env": {
        "PLAYWRIGHT_CHROMIUM_SANDBOX": "1"
      }
    }
  }
}
```

**问题 3：WSL 环境无头浏览器启动失败**

```bash
# 安装 WSL 依赖
sudo apt-get install -y libnss3 libatk-bridge2.0-0 libdrm2 libxkbcommon0 libgbm1 libasound2
```

---

## 三、无障碍快照：Claude Code 的"浏览器之眼"

### 3.1 为什么不用截图？

Playwright MCP 默认使用 **Accessibility Snapshot（无障碍快照）** 而非截图。这是一个关键设计决策：

- **确定性**：无障碍树是结构化文本，不受字体渲染、DPI、抗锯齿影响
- **Token 效率**：一个页面的无障碍树约 500-2000 token，同等截图需要 5000+ token
- **精准定位**：每个元素有唯一的 `ref` 引用，AI 可以精确操作
- **语义理解**：直接暴露角色（role）、名称（name）、状态（state），比像素匹配可靠

### 3.2 快照长什么样

当 Claude Code 调用 `browser_snapshot` 时，返回的是这样的结构：

```
- navigation "Main"
  - link "Home"
  - link "Products"
  - link "About"
- main
  - heading "Welcome to Our Store" [level=1]
  - textbox "Search products..." [ref=s1e3]
  - button "Search" [ref=s1e4]
  - list
    - listitem
      - article
        - heading "Product A" [level=2]
        - text "$29.99"
        - button "Add to Cart" [ref=s1e8]
    - listitem
      - article
        - heading "Product B" [level=2]
        - text "$49.99"
        - button "Add to Cart" [ref=s1e12]
```

每个 `[ref=sXeY]` 就是一个可操作元素的唯一引用。Claude Code 用这些 ref 来执行 `browser_click`、`browser_type` 等操作。

### 3.3 实战：让 Claude Code 探索你的应用

在 Claude Code 中使用以下 prompt：

```
请启动浏览器，访问 http://localhost:3000，获取页面快照，
列出所有可交互元素，并尝试完成一次完整的用户注册流程
```

Claude Code 的执行过程：

```
1. browser_navigate → http://localhost:3000
2. browser_snapshot → 获取页面结构
3. browser_click → 点击 "Sign Up" 按钮 [ref=s1e5]
4. browser_snapshot → 获取注册表单结构
5. browser_fill_form → 填写用户名、邮箱、密码
6. browser_click → 点击 "Submit" [ref=s2e12]
7. browser_snapshot → 验证注册成功提示
```

**关键技巧**：让 Claude Code 在每次关键操作后自动调用 `browser_snapshot`，这样它能根据页面变化做出决策，而不是盲目执行预定义步骤。

---

## 四、三大 Test Agent：从规划到自愈

Playwright v1.56+ 引入了三个内置 AI Test Agent，它们可以直接在 Claude Code 中使用，形成完整的测试流水线。

### 4.1 Planner Agent —— 测试规划器

**作用**：分析应用页面，自动规划出需要覆盖的测试场景和路径。

在 Claude Code 中使用：

```
请使用 Playwright 的 Planner Agent 分析 http://localhost:3000，
为电商购物流程规划测试场景
```

Planner 会自动遍历页面，生成结构化的测试计划：

```markdown
## 测试计划：电商购物流程

### 场景 1：用户注册
- 访问注册页面
- 填写有效信息 → 验证注册成功
- 填写无效邮箱 → 验证错误提示

### 场景 2：商品浏览与搜索
- 访问商品列表页
- 输入关键词搜索 → 验证结果过滤
- 点击分类筛选 → 验证分类正确

### 场景 3：购物车操作
- 添加商品到购物车
- 修改数量 → 验证价格更新
- 删除商品 → 验证购物车更新

### 场景 4：结账流程
- 填写地址信息
- 选择支付方式
- 确认订单 → 验证订单创建
```

### 4.2 Generator Agent —— 测试生成器

**作用**：基于测试计划，自动生成可运行的 Playwright 测试代码。

在 Claude Code 中触发：

```
请根据上面的测试计划，使用 Generator Agent 生成 Playwright 测试代码，
使用 Page Object Model 模式，保存到 tests/e2e/ 目录
```

Claude Code 会生成类似以下的完整测试文件：

```typescript
// tests/e2e/shopping-cart.spec.ts
import { test, expect } from '@playwright/test';
import { HomePage } from '../pages/home.page';
import { ProductPage } from '../pages/product.page';
import { CartPage } from '../pages/cart.page';

test.describe('购物车流程', () => {
  let homePage: HomePage;
  let productPage: ProductPage;
  let cartPage: CartPage;

  test.beforeEach(async ({ page }) => {
    homePage = new HomePage(page);
    productPage = new ProductPage(page);
    cartPage = new CartPage(page);
    await homePage.goto();
  });

  test('添加商品到购物车', async () => {
    await homePage.searchProduct('无线耳机');
    await productPage.selectFirstProduct();
    await productPage.addToCart();
    await productPage.expectCartCount(1);
  });

  test('修改购物车商品数量', async () => {
    await homePage.searchProduct('无线耳机');
    await productPage.selectFirstProduct();
    await productPage.addToCart();
    await cartPage.goto();
    await cartPage.updateQuantity(0, 3);
    await cartPage.expectTotalPrice();
  });

  test('删除购物车商品', async () => {
    await homePage.searchProduct('无线耳机');
    await productPage.selectFirstProduct();
    await productPage.addToCart();
    await cartPage.goto();
    await cartPage.removeItem(0);
    await cartPage.expectEmpty();
  });
});
```

### 4.3 Healer Agent —— 自愈修复器

**作用**：当测试因 UI 变动而失败时，自动分析失败原因，重新定位元素，修复选择器。

这是三个 Agent 中最有价值的。传统 E2E 测试最大的维护成本就来自 UI 变动导致的选择器失效。Healer Agent 的工作流程：

```mermaid
flowchart TD
    A[测试执行失败] --> B[Healer 获取当前页面快照]
    B --> C[分析失败原因：<br/>选择器失效/元素移位/文本变更]
    C --> D[在无障碍树中搜索匹配元素]
    D --> E{找到匹配?}
    E -->|是| F[更新选择器/定位器]
    E -->|否| G[标记为需要人工介入]
    F --> H[重新执行测试]
    H --> I{通过?}
    I -->|是| J[保存修复后的测试]
    I -->|否| C
```

在 Claude Code 中使用 Healer：

```
测试 e2e/shopping-cart.spec.ts 中的"添加商品到购物车"用例失败了，
错误信息是 "Waiting for selector '.add-to-cart-btn' timed out"。
请使用 Healer Agent 修复这个测试
```

Claude Code 会：

1. 启动浏览器访问对应页面
2. 获取当前无障碍快照
3. 通过语义匹配找到新的"Add to Cart"按钮（可能 class 已改为 `btn-add-cart`）
4. 更新 Page Object 中的选择器
5. 重新运行测试验证

---

## 五、Page Object Model 架构：可维护的测试基石

### 5.1 POM 目录结构

```
tests/
├── e2e/                          # E2E 测试用例
│   ├── auth.spec.ts
│   ├── shopping-cart.spec.ts
│   └── checkout.spec.ts
├── pages/                        # Page Objects
│   ├── base.page.ts              # 基础页面类
│   ├── home.page.ts
│   ├── product.page.ts
│   ├── cart.page.ts
│   └── checkout.page.ts
├── fixtures/                     # 测试夹具
│   └── test.fixture.ts
└── helpers/                      # 辅助工具
    ├── assertions.ts
    └── test-data.ts
```

### 5.2 让 Claude Code 生成 POM 代码

向 Claude Code 提供你的页面组件代码或路由结构，让它生成对应的 Page Object：

```
请查看 src/pages/ 目录下的所有页面组件，
为每个页面生成对应的 Page Object Model 类。
使用 data-testid 作为首选定位策略，无障碍角色作为备选。
生成到 tests/pages/ 目录。
```

生成的基础 Page Object 模板：

```typescript
// tests/pages/base.page.ts
import { Page, Locator, expect } from '@playwright/test';

export class BasePage {
  readonly page: Page;

  constructor(page: Page) {
    this.page = page;
  }

  // 通用定位策略：优先 data-testid，备选无障碍角色
  protected getByTestId(id: string): Locator {
    return this.page.getByTestId(id);
  }

  protected getByRole(role: string, options?: Record<string, unknown>): Locator {
    return this.page.getByRole(role as any, options as any);
  }

  protected getByText(text: string): Locator {
    return this.page.getByText(text);
  }

  async goto(path: string = '/') {
    await this.page.goto(path);
    await this.page.waitForLoadState('networkidle');
  }

  async expectVisible(locator: Locator) {
    await expect(locator).toBeVisible({ timeout: 10000 });
  }
}
```

```typescript
// tests/pages/home.page.ts
import { BasePage } from './base.page';
import { Page, Locator, expect } from '@playwright/test';

export class HomePage extends BasePage {
  // 定位器 - 使用语义化属性
  readonly searchInput: Locator;
  readonly searchButton: Locator;
  readonly productCards: Locator;
  readonly cartBadge: Locator;

  constructor(page: Page) {
    super(page);
    this.searchInput = this.getByTestId('search-input');
    this.searchButton = this.getByTestId('search-button');
    this.productCards = this.page.locator('[data-testid="product-card"]');
    this.cartBadge = this.getByTestId('cart-badge');
  }

  async goto() {
    await super.goto('/');
  }

  async searchProduct(query: string) {
    await this.searchInput.fill(query);
    await this.searchButton.click();
    await this.page.waitForResponse('**/api/products**');
  }

  async getProductCount(): Promise<number> {
    return this.productCards.count();
  }

  async getCartCount(): Promise<string> {
    return this.cartBadge.textContent() ?? '0';
  }
}
```

### 5.3 定位器策略优先级

让 Claude Code 遵循以下定位器优先级（写进 CLAUDE.md 或项目的 `.claude/instructions`）：

```markdown
## E2E 测试定位器策略

按优先级从高到低：
1. `data-testid` 属性 — 最稳定，不受 UI 文案变动影响
2. 无障碍角色 — `getByRole('button', { name: 'Submit' })`
3. 无障碍标签 — `getByLabel('Email address')`
4. 文本内容 — `getByText('Welcome back')`（仅当文案不常变）
5. CSS 选择器 — 最后手段，必须包含语义化的 class 名
```

在组件代码中主动添加 `data-testid`：

```tsx
// src/components/ProductCard.tsx
export function ProductCard({ product }: { product: Product }) {
  return (
    <article data-testid="product-card">
      <h2 data-testid="product-name">{product.name}</h2>
      <span data-testid="product-price">${product.price}</span>
      <button
        data-testid="add-to-cart"
        onClick={() => addToCart(product.id)}
      >
        Add to Cart
      </button>
    </article>
  );
}
```

---

## 六、完整实战：电商应用 E2E 测试流水线

### 6.1 项目初始化

```bash
# 创建 Next.js 电商项目（如果还没有）
npx create-next-app@latest my-store --typescript --tailwind --app
cd my-store

# 安装 Playwright
npm install -D @playwright/test
npx playwright install chromium

# 创建测试目录结构
mkdir -p tests/{e2e,pages,fixtures,helpers}
```

### 6.2 配置 Playwright

```typescript
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests/e2e',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [
    ['html', { open: 'never' }],
    ['json', { outputFile: 'test-results/results.json' }],
  ],
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
});
```

### 6.3 让 Claude Code 一键生成全套测试

在项目根目录启动 Claude Code，输入：

```
请分析 src/app/ 下的所有页面路由和组件，为我的电商应用生成完整的 E2E 测试套件。

要求：
1. 使用 Page Object Model 模式
2. 覆盖：注册、登录、商品浏览、搜索、购物车、结账
3. 每个场景包含正向和反向测试
4. 使用 data-testid 定位
5. 保存到 tests/ 目录
```

Claude Code 会：
1. 读取 `src/app/` 目录下的路由和页面组件
2. 分析每个页面的交互元素
3. 规划测试场景
4. 生成 Page Object 类
5. 生成测试用例文件
6. 生成测试夹具（登录态等）

### 6.4 自测工作流：开发者的日常

开发新功能后，让 Claude Code 自测：

```
我刚完成了商品评论功能的开发。
请：
1. 启动应用
2. 通过浏览器验证评论功能（发布评论、查看评论、删除评论）
3. 为评论功能生成 E2E 测试
4. 运行测试并报告结果
```

Claude Code 的执行流程：

```mermaid
sequenceDiagram
    participant Dev as 开发者
    participant CC as Claude Code
    participant MCP as Playwright MCP
    participant App as 本地应用

    Dev->>CC: 验证评论功能 + 生成测试
    CC->>MCP: browser_navigate /localhost:3000
    MCP->>App: HTTP Request
    App-->>MCP: HTML Response
    MCP-->>CC: 页面加载完成
    CC->>MCP: browser_snapshot
    MCP-->>CC: 无障碍树 (含评论区域)
    CC->>MCP: browser_click "Write Review"
    CC->>MCP: browser_fill_form
    CC->>MCP: browser_click "Submit"
    CC->>MCP: browser_snapshot
    MCP-->>CC: 验证评论已发布
    CC->>CC: 生成 E2E 测试代码
    CC->>App: npx playwright test
    App-->>CC: 测试结果
    CC-->>Dev: 报告：3个场景全部通过
```

### 6.5 CI 集成

将 AI 生成的测试接入 GitHub Actions：

```yaml
# .github/workflows/e2e.yml
name: E2E Tests
on:
  pull_request:
    branches: [main]

jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install dependencies
        run: npm ci

      - name: Install Playwright
        run: npx playwright install --with-deps chromium

      - name: Build application
        run: npm run build

      - name: Run E2E tests
        run: npx playwright test

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: playwright-report/
```

---

## 七、Healer 深度实战：选择器自愈流水线

### 7.1 触发条件

在以下场景下让 Claude Code 使用 Healer Agent：

- CI 中测试失败，收到 `locator.waitFor: Timeout` 错误
- 代码重构后批量测试飘红
- 依赖的第三方组件库更新导致 DOM 结构变化

### 7.2 自愈流程实战

在 Claude Code 中执行：

```
运行 npx playwright test，发现 tests/e2e/auth.spec.ts 失败。
请分析失败原因，使用 Healer 修复所有失败用例，
修复后重新运行测试确认通过
```

Claude Code 的处理步骤：

**第一步：诊断**

```
$ npx playwright test --reporter=json 2>&1 | tail -20

Error: locator.waitFor: Waiting for selector '[data-testid="login-btn"]' failed
  at LoginPage.clickLogin (tests/pages/login.page.ts:15)
```

**第二步：打开浏览器获取当前状态**

Claude Code 调用 Playwright MCP：
- `browser_navigate` → 访问登录页
- `browser_snapshot` → 获取当前无障碍树
- 分析树结构，发现登录按钮现在是 `<button role="button" name="Sign in">`

**第三步：更新 Page Object**

```typescript
// 修复前
readonly loginButton = this.getByTestId('login-btn');

// 修复后 - 开发者改了 data-testid
readonly loginButton = this.getByTestId('sign-in-btn');
```

**第四步：重新运行验证**

```bash
npx playwright test tests/e2e/auth.spec.ts --retries=0
```

### 7.3 批量自愈

当大规模重构后，一次性修复所有失败测试：

```
我们的 Button 组件从 <button class="btn"> 迁移到了 <Button variant="primary">，
导致 50+ 测试失败。请：
1. 运行全部测试，收集失败列表
2. 对每个失败用例使用 Healer 修复
3. 生成修复报告：哪些自动修复了，哪些需要人工介入
```

---

## 八、高级技巧

### 8.1 保持登录态复用

```typescript
// tests/fixtures/auth.fixture.ts
import { test as base, Page } from '@playwright/test';

type AuthFixture = {
  authenticatedPage: Page;
};

export const test = base.extend<AuthFixture>({
  authenticatedPage: async ({ browser }, use) => {
    const context = await browser.newContext({
      storageState: 'tests/fixtures/auth-state.json',
    });
    const page = await context.newPage();
    await use(page);
    await context.close();
  },
});
```

生成登录态文件：

```
请使用浏览器完成登录流程，将登录状态保存到 tests/fixtures/auth-state.json
```

Claude Code 会通过 Playwright MCP 执行登录，然后调用 `page.context().storageState()` 保存状态。

### 8.2 网络请求 Mock

```typescript
// tests/helpers/mock-server.ts
import { Page } from '@playwright/test';

export async function mockProductAPI(page: Page) {
  await page.route('**/api/products', async (route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        products: [
          { id: 1, name: 'Wireless Headphones', price: 79.99 },
          { id: 2, name: 'USB-C Cable', price: 12.99 },
        ],
      }),
    });
  });
}
```

让 Claude Code 基于项目的 API 路由自动生成 mock：

```
请分析 src/app/api/ 下的所有 API 路由，
为每个路由生成 mock 函数，包含正常响应和错误响应两种场景
```

### 8.3 视觉回归测试

```typescript
// tests/e2e/visual-regression.spec.ts
import { test, expect } from '@playwright/test';

test('首页视觉回归', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveScreenshot('home-page.png', {
    maxDiffPixelRatio: 0.01,
    threshold: 0.2,
  });
});
```

### 8.4 并行测试执行优化

```typescript
// playwright.config.ts 中的并行配置
export default defineConfig({
  // 按文件级并行
  fullyParallel: true,
  workers: process.env.CI ? 4 : '50%',
  // 分片执行（CI 多机器）
  // shard: '1/4',
});
```

在 Claude Code 中运行分片：

```bash
# 第1个分片（共4个）
npx playwright test --shard=1/4
```

---

## 九、性能与成本优化

### 9.1 Token 消耗控制

Playwright MCP 的无障碍快照每次约消耗 500-2000 token。减少不必要快照的策略：

| 策略 | 说明 | 节省 |
|------|------|------|
| 限制快照深度 | 使用 `depth` 参数只获取关键层级 | 40-60% |
| 精准快照目标 | 对特定元素做 `browser_snapshot(target=ref)` | 50-70% |
| 合并连续操作 | 填表时用 `browser_fill_form` 代替多次 `browser_type` | 30% |
| 缓存页面状态 | 相同页面跳转时复用快照 | 20-30% |

### 9.2 测试执行速度

```typescript
// playwright.config.ts 速度优化
export default defineConfig({
  use: {
    // 关闭不必要的资源加载
    bypassCSP: true,
    // 超时设置
    navigationTimeout: 15000,
    actionTimeout: 10000,
  },
  // 禁用不必要的跟踪
  trace: 'off',  // CI 中改为 'on-first-retry'
  screenshot: 'off', // CI 中改为 'only-on-failure'
  video: 'off',  // CI 中改为 'retain-on-failure'
});
```

---

## 十、从探索到回归：完整工作流总结

```mermaid
flowchart TB
    subgraph 开发阶段
        A[编写新功能] --> B[Claude Code 自测]
        B --> C{通过?}
        C -->|否| D[修复代码]
        D --> B
        C -->|是| E[提交 PR]
    end

    subgraph 测试生成
        E --> F[Planner Agent<br/>规划测试场景]
        F --> G[Generator Agent<br/>生成测试代码]
        G --> H[运行测试验证]
    end

    subgraph 持续维护
        I[CI 运行测试] --> J{全部通过?}
        J -->|是| K[合并代码]
        J -->|否| L[Healer Agent<br/>自动修复]
        L --> M{修复成功?}
        M -->|是| N[更新测试代码]
        M -->|否| O[人工介入]
        N --> I
        O --> P[开发者修复]
        P --> I
    end

    H --> I
```

### 快速命令参考

| 目的 | Claude Code 命令/Prompt |
|------|------------------------|
| 探索页面 | `启动浏览器访问 localhost:3000，获取页面快照` |
| 自测功能 | `验证注册功能是否正常工作` |
| 生成测试 | `为购物车功能生成 E2E 测试` |
| 修复失败 | `测试失败了，请修复所有失败用例` |
| 批量运行 | `运行全部 E2E 测试并生成报告` |
| 视觉测试 | `对首页做视觉回归测试` |
| 性能审计 | `检查首页加载性能，报告 LCP/FID/CLS` |

---

## 延伸阅读

- [Playwright MCP 官方文档](https://playwright.dev/docs/getting-started-mcp) — 微软官方的 MCP 服务器配置与工具参考
- [Playwright Test Agents](https://playwright.dev/docs/test-agents) — Planner/Generator/Healer 三大 Agent 官方说明
- [Playwright Page Object Model](https://playwright.dev/docs/pom) — POM 模式最佳实践
- [microsoft/playwright-mcp GitHub](https://github.com/microsoft/playwright-mcp) — 源码与最新 Release
- [Testing with Playwright and Claude Code](https://nikiforovall.blog/ai/2025/09/06/playwright-claude-code-testing.html) — 实战案例与 MCP 集成指南

---

## 参考来源

1. [Playwright MCP — Getting Started](https://playwright.dev/docs/getting-started-mcp) — 微软官方 Playwright MCP 文档，配置选项与工具列表
2. [Playwright Test Agents](https://playwright.dev/docs/test-agents) — Planner、Generator、Healer 三大 Test Agent 官方文档
3. [microsoft/playwright-mcp GitHub Repository](https://github.com/microsoft/playwright-mcp) — Playwright MCP Server 源码，工具定义与版本更新
4. [Playwright AI Ecosystem 2026: MCP, Agents & Self-Healing Tests](https://testdino.com/blog/playwright-ai-ecosystem) — 2026 年 Playwright AI 生态全景
5. [E2E Testing with Claude Code: Playwright/Cypress Practical Guide](https://claudecode-lab.com/en/blog/claude-code-e2e-testing/) — Claude Code E2E 测试实战指南

---

> **训练营适用性评估**：本教程适合"AI 辅助工程"中级训练营（3-4 天课时）或"测试自动化"专题工作坊（2 天）。建议前置半天的基础 Playwright 入门，后接半天的项目实战。对 QA 团队转型 AI 测试的培训尤为适用，预计核心教学时长 6-8 小时，含动手实验 3-4 小时。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
