<!-- title: 拆webapp-testing：让Claude自己考自己 -->

# 拆webapp-testing：让Claude自己考自己

## 概述

这是本栏 Skills 生态观察的第 2 轮单件深拆。前几期拆过 superpowers、mcp-builder、官方 docx/pdf 家族、Humanizer 等明星件，本期选了一个栏目历史上从未拆过的新面孔：`webapp-testing`——Anthropic 官方 example-skills 插件家族里的「网页自测件」。它的任务只有一句话：让 Claude 写完网页之后，自己打开浏览器把它测了。但真正值得拆的不是功能，而是它的写法：全文不到一百行的 SKILL.md，把「上下文经济学」刻进了每一行——它会明确禁止 Claude 去读自己的脚本源码，理由是“会污染你的上下文窗口”。本期逐段拆它的 SKILL.md，对照同门两件（doc-coauthoring、canvas-design）讲清官方示例的三种设计物种，最后给出六条可以直接抄去写你自己第一个 Skill 的心法。本文全部引文来自本机安装的插件原文，未采信二手转述。

## 一、为什么是它

翻遍本栏 150 条选题史：官方件拆过 docx、pdf、xlsx、skill-creator、theme-factory、web-artifacts-builder、frontend-design（审美件），社区件拆过 superpowers、Humanizer、planning-with-files——但 `webapp-testing` 一直没人动过。它是官方 example-skills 家族里最「工具型」的一件：不谈审美、不谈流程仪式感，通篇都在解决一个硬问题——**Agent 写完的网页，怎么在没有测试工程师坐旁边的情况下完成验收**。

更有意思的是它的物种属性。把官方 example-skills 插件里的三份 SKILL.md 原文摆在一起看，会发现同一棵树上结出了三种完全不同的果子：

| 物种 | 代表件 | 核心资产 | 设计重心 |
|------|--------|----------|----------|
| 工具型 | webapp-testing | 一个黑盒脚本 + 决策树 | 管住 Agent 的手和上下文 |
| 流程型 | doc-coauthoring | 三阶段状态机 + 退出条件 | 管住对话的节奏和用户预期 |
| 审类型 | canvas-design | 一篇审美宣言 + 反复催眠 | 管住输出品的品味下限 |

三种物种对应三类任务：工具型适合「有明确成败的动作」，流程型适合「多轮协作的长会话」，审类型适合「主观但有毒.Tx 隙的产出」。webapp-testing 是工具型的官方样板，这就是本期拆它的理由。

**三物种分家谱系：**

```mermaid
flowchart TD
    R["官方示例插件三件"]
    R --> A["工具型 webapp-testing"]
    R --> B["流程型 doc-coauthoring"]
    R --> C["审类型 canvas-design"]
    A --> A1["脚本当黑盒跑"]
    A --> A2["决策树派活"]
    B --> B1["三阶段状态机"]
    B --> B2["新开Claude当读者"]
    C --> C1["宣言式审美催眠"]
    C --> C2["零脚本纯约束"]
```

## 二、评测对比表

评分基于本栏对三份 SKILL.md 原文的通读比对，1–5 星；「上手难度」5 星代表最省心。社区活跃度一项，因三件同属官方插件捆绑分发、外部实时热度数据本次未能联网核验，改按发行渠道计分并如实标注。

| 维度（权重） | webapp-testing | doc-coauthoring | canvas-design |
|------|------|------|------|
| 功能完整度（25%） | ★★★★☆ | ★★★★☆ | ★★★★☆ |
| 设计质量（25%） | ★★★★★ | ★★★★★ | ★★★★☆ |
| 实战效果（20%） | ★★★★☆ | ★★★★☆ | ★★★☆☆ |
| 上手难度（15%） | ★★★☆☆ | ★★★★★ | ★★★★★ |
| 发行与分发（15%） | ★★★★★ | ★★★★★ | ★★★★★ |
| **加权总分** | **4.25** | **4.55** | **4.10** |

一个耐人寻味的结论：本轮深拆的主角总分只排第二。doc-coauthoring 靠零依赖、张口就赢在上手分。但 webapp-testing 的「设计质量」满分不是白给的——下面逐段看它把分挣在了哪里。

## 三、SKILL.md 逐段拆解

以下引文均为本机 `example-skills` 插件缓存中该件原文的逐字摘录。

### 第一段：一句话定使命

> To test local web applications, write native Python Playwright scripts.

标题是 `# Web Application Testing`，正文第一句就把三件事钉死：测试对象（**local** web applications，不是线上站点）、实现路径（写**原生 Python** Playwright 脚本，而不是调某个封装好的测试框架）、动作形态（**write**，让 Claude 现场写脚本，而不是背一套测试用例库）。好的 SKILL.md 开头都是这种密度——一句话同时回答「干什么、怎么干、干到什么边界」。注意 local 这个限定词：它把生产环境压测、线上安全扫描全部划出管辖范围，触发边界干净。

### 第二段：黑盒教条——全文最值钱的六行

> **Helper Scripts Available**:
> - `scripts/with_server.py` - Manages server lifecycle (supports multiple servers)
>
> **Always run scripts with `--help` first** to see usage. DO NOT read the source until you try running the script first and find that a customized solution is abslutely necessary. These scripts can be very large and thus pollute your context window. They exist to be called directly as black-box scripts rather than ingested into your context window.

这是整份文件的设计核心，值得逐行读：

- **`--help` first**：把 Unix 命令行的老规矩搬给 Agent。`--help` 输出只有几十行，读源码可能几百上千行——先用最便宜的方式弄清接口，这是给上下文窗口省钱。
- **DO NOT read the source**：全大写的禁令只出现这一次。作者非常清楚 LLM 的坏习惯——拿到一个脚本路径就想先通读一遍「理解一下」。对人是好习惯，对上下文只有 20 万 token 的 Agent 是自杀行为。
- **pollute your context window**：作者用的词是「污染」。这个隐喻说明 Skill 作者的设计意识已经从「写文档给人看」进化到「管理一个有限内存的工人的操作规程」。
- **abslutely**：原文里这个单词就是拼错的（应为 absolutely）。这反而是真实性的注脚——官方件也是手写的，而 Claude 读指令靠意图不靠拼写，错字不影响执行。你自己写 SKILL.md 时不必有错字焦虑。

这一段给所有 Skill 作者的启示是：**你的 Skill 不只是教 Agent 干活，还要教它「别看什么」**。资源文件写得越强，越要配一条「禁止阅读」的护栏。

### 第三段：决策树——把自由裁量权收走

> ```
> User task → Is it static HTML?
>     ├─ Yes → Read HTML file directly to identify selectors
>     │         ├─ Success → Write Playwright script using selectors
>     │         └─ Fails/Incomplete → Treat as dynamic (below)
>     └─ No (dynamic webapp) → Is the server already running?
>         ├─ No → Run: python scripts/with_server.py --help ...
>         └─ Yes → Reconnaissance-then-action: ...
> ```

作者没有用段落描述「根据情况选择合适的方法」，而是画了一棵 ASCII 决策树。两个分叉点选得极准：**是不是静态 HTML**（决定了要不要起服务器）、**服务器是否已在运行**（决定了要不要托管）。每个叶节点直接给出下一个动作，没有任何「你可以考虑……」式的松散建议。LLM 在开放选项面前会摇摆，在二叉判断前不会——用判断题代替选择题，是工具型 Skill 提高执行确定性的第一杠杆。

### 第四段：with_server.py 用法——例子里的细节全是私货

```bash
python scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.py
```

单服务器例子看似平平无奇，三个细节都是设计：

- **`npm run dev` + 端口 5173**：5173 是 Vite 的默认端口，多服务器例子里的 3000 是后端惯例端口。作者故意用真实世界的默认值，让大多数人拿到的例子和自己的项目严丝合缝，抄过来就能跑。
- **`--port 5173`**：脚本要等这个端口真的开始监听才放行后面的命令——「服务就绪检测」这个最容易翻车的点被黑盒吸收了，SKILL.md 一个字都不用解释。
- **裸 `--`**：约定俗成的分隔符，横线之后全是给你的自动化脚本用的参数。两个 `--server` 可以叠着写，后端前端一次托管——「supports multiple servers」这七个字的承诺由例子兑现。

配套的 Playwright 模板更是把指令埋进了代码注释：

```python
browser = p.chromium.launch(headless=True) # Always launch chromium in headless mode
page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute
```

Claude 写脚本时会整段照抄模板，于是模板里的注释就成了随代码一起被执行的指令：headless 模式和 networkidle 等待，一个管不打扰人、一个管单页应用最大的坑。**把行为约束写进被复制的代码，而不是写进希望被记住的散文**——这是官方件才有的老辣。

### 第五段：侦察后行动——不许猜选择器

> 1. Navigate and wait for networkidle
> 2. Take screenshot or inspect DOM
> 3. Identify selectors from rendered state
> 4. Execute actions with discovered selectors

这个被命名为 Reconnaissance-then-action（侦察后行动）的四步模式，治的是 LLM 自动化测试的头号绝症：**幻觉选择器**。模型没看过渲染后的页面，会凭 HTML 直觉编一个 `page.click('#submit-btn')`，然后对着 `TimeoutError` 死循环。四个步骤的本质是一道铁律——先看渲染结果，再从看到的 DOM 里取选择器，禁止凭空捏造。配套的侦察代码只给三行：全页截图、`page.content()`、`page.locator('button').all()`，全是只读动作。

### 第六段：Common Pitfall——只防一个坑

> ❌ **Don't** inspect the DOM before waiting for `networkidle` on dynamic apps
> ✅ **Do** wait for `page.wait_for_load_state('networkidle')` before inspection

整份文件的「避坑指南」只写了一个坑。这不是偷懒，是克制：作者很清楚 SPA 场景下「DOM 还没渲染完就去查元素」是发生频率最高的失败，把它用 ❌/✅ 对照钉在显眼处；其他次要坑全部降级到 Best Practices 一句话带过。反面教材是那些把十条注意事项平铺的 Skill——权重被摊平，等于没有权重。

### 第七段：三层资源披露——SKILL.md 只做前台

> **Reference Files**:
> - `examples/` - Examples showing common patterns:
>   - `element_discovery.py` - Discovering buttons, links, and inputs on a page
>   - `static_html_automation.py` - Using file:// URLs for local HTML
>   - `console_logging.py` - Capturing console logs during automation

至此整个件的资源结构清楚了，是一个三层按需加载的体系：

```mermaid
flowchart TD
    L1["第一层 SKILL.md 触发即入上下文"]
    L2["第二层 scripts 黑盒只执行"]
    L3["第三层 examples 按需才读"]
    L1 --> L2
    L1 --> L3
```

第一层是常驻的 SKILL.md（决策树、模板、铁律）；第二层是 `scripts/with_server.py`——只准执行不准阅读的黑盒；第三层是 `examples/` 里三个示例脚本，每个配一行用途说明（发现页面元素、静态 HTML 用 file:// 协议测、抓浏览器 console 日志），只在撞上对应场景时才值得打开。需要坦白的是，本文对第二、三层也遵循了它的黑盒纪律——只依据 SKILL.md 内文对它们的定位与承诺做拆解，未通读其源码。**这恰好是这份 SKILL.md 想教会 Agent 的读法**：文件自己把自己的用法说清楚了，读懂前台就够了。

Best Practices 收尾五条也全是省钱逻辑：黑盒优先、用 `sync_playwright()` 写同步脚本、用完关浏览器、选择器用 `text=`/`role=`/CSS/ID 这类语义化写法、按需加等待。没有一条超过一行。

## 四、适用与不适用

**适合交给它的活：**

- 本地 dev server 写完后的冒烟自测：「点一遍主要按钮，看 console 有没有报错」
- 前后端分离项目的联调验证（双 `--server` 托管一次跑通）
- 静态 HTML 原型的结构验证与抓取
- 提 PR 前自己先把 E2E 主路径走一遍，别等 CI 红灯

**不适合的活（原文 local 限定 + 模板只给 chromium headless 推出）：**

- 线上生产环境的任何测试、压测、安全扫描
- 多浏览器兼容矩阵、移动端真机测试——模板只写了 chromium 无头模式
- 像素级视觉回归对比——它给截图方法，不给 diff 工具
- 性能测试——networkidle 等待策略恰恰是性能测试的大敌

## 五、安装与使用

本机缓存路径（`plugins/cache/anthropic-agent-skills/example-skills/`）显示它随 Anthropic 官方的 agent-skills 市场以 example-skills 插件捆绑分发，上游仓库为 `github.com/anthropics/skills`。实时 Star 数据本次未能联网核验，不做引用。

```bash
# 方式一：已装 example-skills 插件的用户零安装
# 在 Claude Code 里直接说：
# 「测一下 localhost:5173 这个页面：逐个点主要按钮，
#   截图并检查 console 有没有报错」

# 方式二：从官方仓库取件（通用做法）
git clone https://github.com/anthropics/skills
cp -r skills/webapp-testing ~/.claude/skills/    # 个人级，全项目可用
# 或复制进项目的 .claude/skills/，随仓库共享给团队

# 依赖一次性装好
pip install playwright
playwright install chromium
```

## 六、抄它六条：写你自己的第一个工具型 Skill

1. **第一句钉死边界**：干什么、怎么干、不干什么，一句话说完，限定词（local）要舍得写。
2. **给资源配黑盒禁令**：脚本强就写上「先 `--help`，禁止读源码」，把上下文窗口当内存条管理。
3. **判断题代替选择题**：用 ASCII 决策树分派路径，别给 Agent 留摇摆空间。
4. **约束埋进被复制的代码**：模板注释里的 `CRITICAL` 会随复制粘贴自动执行，比散文可靠。
5. **避坑只写最高频的一个**：❌/✅ 对照，一条就够，多了等于没有。
6. **例子用真实默认值**：5173、3000、`npm run dev`，让读者抄过来就能跑，就是最好的文档。

## 推荐排行榜

- **最值得拆抄的设计**：webapp-testing——上下文经济学的官方教科书
- **新手第一份该读的 SKILL.md**：canvas-design——零脚本零依赖，纯看话术怎么塑造输出
- **最像成熟产品流程的**：doc-coauthoring——退出条件、用户否决权、新开 Claude 当读者的验收设计一应俱全
- **综合分最高**：doc-coauthoring（4.55）——但如果你要写的是「干活型」而非「聊天型」Skill，webapp-testing 才是那本该抄的范本

## 参考来源

1. webapp-testing SKILL.md 原文（本机 example-skills 插件缓存逐字引录，路径 `plugins/cache/anthropic-agent-skills/example-skills/` 下 `skills/webapp-testing/SKILL.md`）— 本文核心拆解对象
2. doc-coauthoring SKILL.md 原文（同上插件缓存）— 流程型对照样本
3. canvas-design SKILL.md 原文（同上插件缓存）— 审类型对照样本
4. [anthropics/skills](https://github.com/anthropics/skills) — 上述示例件的上游官方仓库；本文写作环境未能联网，实时 Star 数与外部评测未予引用，读者可自行核验

> [!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)
