4.4 webapp-testing:用 Playwright 测自己的应用

它是什么

webapp-testing 的官方描述:用 Playwright 与本地 Web 应用交互和测试的工具箱。

在 19 个官方技能里,它是工程属性最强的一个。多数技能给的是方法论或创作指导,它给的是一套可执行的浏览器操作原语——导航、点击、输入、截图、读取可访问性树——模型照着就能驱动真实浏览器。装它等于给你的 agent 配了一个不知疲倦的 QA。

装法与 4.1 相同,浅克隆后复制技能目录:

mkdir -p ~/.dsh/skills
git clone --depth 1 https://github.com/anthropics/skills.git /tmp/anthropic-skills
cp -r /tmp/anthropic-skills/skills/webapp-testing ~/.dsh/skills/

复制完新开一个会话,/webapp-testing 能直调即算装好。

为什么浏览器测试必须技能化

“点一下看看行不行”这种手工测试有三个致命局限:不可重复、不可回归、覆盖不了分支状态。同一个回归跑十遍,十个结果;分支状态(空数据、报错态、加载中)没人手点得过来。

而让模型直接写测试脚本,常见问题是——它不知道自己看到的页面长什么样。模型写得出 page.click,但不知道点击之后页面变成了什么样:弹窗遮住了按钮、请求转圈三秒、表单其实有前端校验。没有结构化的页面观测手段,写出来的脚本要么选择器过时,要么断言写在想象的页面上,一跑就红。

webapp-testing 解决的是后半段:给模型一套结构化的浏览器交互原语,让它能真正“看到”并操作页面——看到的是可访问性树,不是猜。

可访问性树优于截图

这个技能基于 Playwright,而 Playwright 有个关键设计:通过结构化可访问性树驱动浏览器,而不是靠截图识别。

维度 可访问性树 截图识别
速度 快,直接读结构 慢,每步都要截图再识别
稳定性 高,DOM 语义不受样式改动影响 低,受视觉噪声影响
获取表单值 直接读节点属性 要 OCR,还可能读错
定位元素 按 role / name 语义定位 按坐标或图像匹配

逐行看:速度上,截图路线每交互一步都要渲染整页再送识别,树路线一步一个结构快照;稳定性上,你把按钮换个颜色,截图路线的图像匹配可能就失效,树路线只要 role 和 name 没变就照样命中;表单值上,OCR 把 0 认成 O 是常事,树路线读的是节点属性,不存在这问题;定位上,按语义定位意味着“提交按钮”,按坐标定位意味着“屏幕上第 300 像素那个方块”,后者窗口一抖就偏。

这也是微软官方 Playwright MCP 服务器同样采用可访问性树的原因——microsoft/playwright-mcp 的产品说明就是“通过结构化可访问性树驱动真实浏览器,比截图更快更可靠”。两条路线不谋而合:业界已经收敛到这个答案。看到有人用“截图加视觉识别”的方案测浏览器,可以直接打个问号。

给模型写测试提示词的模板

用这个技能时,提示词越像下面这样,跑得越稳:

用 webapp-testing 技能对本地 <端口> 的应用做 <类型> 测试:
步骤:<A → B → C>
每步:<是否截图 / 读取哪个元素>
断言:<具体期望,如“列表出现新行且文案为 X”>
失败处理:上报当时页面状态,不要自作主张重跑

关键在“断言具体”和“失败不擅自重试”。断言含糊,模型就报“看起来正常”;失败自动重试,你会分不清是修好了还是蒙过了。

典型任务

任务一:冒烟测试。

用 webapp-testing 技能对本地 3000 端口的应用做冒烟测试:
登录 → 进入订单页 → 创建一条测试订单 → 确认出现在列表。
每步截图,失败时报出当时页面状态。

冒烟测试的意义是快速确认“主流程没死”。提示词里“每步截图,失败时报出当时页面状态”是给自己留证据——失败了不用复现,翻截图就行。

任务二:表单校验回归。

用 webapp-testing 技能测试注册表单:
空提交、错误邮箱、弱密码、正常提交四种情况,
记录每种情况的提示文案,与预期文案比对。

这个任务示范了分支覆盖:四种输入对应四条路径,比手点一遍全。提示文案比对属于回归——后端改了校验规则,前端文案没跟着变,这种裂缝只有脚本抓得到。

任务三:视觉走查。

用 webapp-testing 技能遍历 /settings 的所有 tab,
每 tab 截图,检查控制台有无报错。

视觉走查加控制台检查,一箭双雕:截图留给你看 UI,控制台报错抓那些“页面看着正常其实一屏红”的问题。

三个任务的共同点:流程明确、断言具体、结果可留存。写提示词时照着这个模板来,别写“测试一下这个网站”——那是探索任务,该用 MCP。

失败排查表

现象 先查什么
元素点不到 是否有弹窗 / 遮罩;改用 role+name 定位
断言时灵时不灵 是否在等异步,加显式等待而非固定 sleep
读到的文本是旧值 页面没刷新完就断言,补等待条件
控制台一堆红但页面正常 确认是第三方脚本报错还是自身逻辑

与浏览器 MCP 的分工

DeepSeek Harness 里浏览器能力有两条路:

路径 形态 适合
webapp-testing 技能 技能(指令 + 脚本) 测试自己的本地应用
Playwright / Chrome DevTools MCP MCP 服务器 需要模型自主探索的浏览器任务

前者更像“按脚本执行并报告”:流程你定,它跑完给你每步状态;后者更像“给你一个浏览器自己玩”:目标是开放的,模型自己决定点哪、看哪、下一步干什么。

所以分工很清楚:测试选前者,因为测试要的是可重复和可回归,流程必须钉死;探索选后者,因为探索要的是临场应变,目标没法预先写全。反着用就两头不讨好——用技能做开放式探索,流程框死了探索;用 MCP 做回归测试,每次路径都不一样,回归失去意义。

两条路的具体装法:MCP 方案见 MCP 书的 3.1 Playwright 与 3.2 Chrome DevTools 两节;本技能的装法见上文,复制目录即用。

小结

  • webapp-testing 是基于 Playwright 的本地 Web 应用测试工具箱,19 个技能里工程属性最强。
  • 模型写测试的常见病是不知道页面长什么样,这个技能用可访问性树把页面结构交给它。
  • 可访问性树驱动优于截图识别:更快、更稳、能直接读值;微软 Playwright MCP 走同一路线。
  • 测试本地应用用这个技能;开放式浏览器探索用 MCP。

延伸阅读