网页“看起来正常”,不等于搜索、筛选和按钮都能用。尤其是 AI 写出的前端,常见问题是控件有样式、交互却没有实现。webapp-testing Skill 的用途,是帮助 Claude 按可复查的流程检查本地网页功能,生成测试脚本、截图和问题记录。

它来自 Anthropic 官方 anthropics/skills 仓库,核心依赖 Python Playwright。Skill 本身主要提供操作方法和辅助脚本,不是独立浏览器,也不会自动修复全部问题。本篇以一个自建的待办搜索页面为例,从安装、准备测试对象到失败定位,完成一轮可重复的功能验收。

本文提供官方源码整理包,版本为 commit `2c5958ecac7c`,对应完整提交 2c5958ecac7cee2b583967a2c4981d0f4a75c579。示例代码和预期结果不冒充本站对读者项目的亲测结论;下载包内的第三方脚本未在本站制作过程中执行。

一、来源、范围与包内容

  1. 官方来源:Anthropic 的 Skills 示例仓库,具体路径为 skills/webapp-testing。本篇介绍的是这一 Skill,不是同名的第三方插件。
  2. 主要用途:检查本地前端功能、观察界面行为、捕获截图和浏览器日志。它不能仅凭一张截图证明支付、数据库写入或服务端权限全部正确。
  3. 适用工具:官方 README 提供 Claude Code 插件市场的使用方式。其他支持 Agent Skills 的工具仍需检查自己的加载机制和执行能力,不能默认所有工具都能原样调用。
  4. 许可证:本包中的 LICENSE.txt 为 Apache License 2.0。再分发时保留许可与适用声明,自己的测试页面、依赖和被测试项目也有各自的权利边界。
  5. 下载范围:只整理该 Skill 目录、原有示例和许可文件,另附中文来源说明。没有把 Playwright 浏览器二进制或 Python 环境打包进去,下载后仍需准备依赖。

解压后可看到以下结构:

webapp-testing/
  SKILL.md
  LICENSE.txt
  scripts/with_server.py
  examples/element_discovery.py
  examples/static_html_automation.py
  examples/console_logging.py
来源与安装说明.txt

SKILL.md 说明测试思路;with_server.py 用于启动测试服务、等待端口并执行测试命令;examples 提供元素发现、静态页面和日志采集的参考。不要把“目录存在”当成插件已经安装成功。

webapp-testing 从测试规则、浏览器操作到断言与证据的工作路径示意

上图为原创测试流程示意,不是 Claude 或 Playwright 的界面截图。

二、安装 Skill 与浏览器依赖

先准备可正常使用的 Claude Code、Python 环境,以及你有权测试的本地项目。第一次使用可通过官方 README 给出的插件市场方式安装:在 Claude Code 会话中运行下面的命令,而不是在普通 PowerShell 中运行。

/plugin marketplace add anthropics/skills
/plugin install example-skills@anthropic-agent-skills

随后明确提出“使用 webapp-testing 检查本地网页”。插件管理界面应能确认已安装对应插件,实际使用时再确认 Skill 被加载。在线插件可能更新到比本文源码包更晚的版本;要复现本文辅助脚本,请使用下载包内的固定版本文件,避免把不同版本的路径混在一起。

浏览器自动化依赖需单独安装。下面使用 Windows PowerShell,在新建练习目录操作:

py -m venv .venv
.\.venv\Scripts\python.exe -m pip install playwright
.\.venv\Scripts\python.exe -m playwright install chromium

浏览器安装需要下载对应文件,不等于系统里有 Chrome 就已经满足 Playwright 要求。Linux 还可能需要系统依赖,按官方安装文档处理,不盲目复制其他发行版的软件包列表。记录实际 Python、Playwright 版本,后续排错时使用同一个虚拟环境。

三、准备一个结果明确的测试页面

新建 site 目录,在其中保存 UTF-8 编码的 index.html。这是本文自写的练习页面,使用非敏感待办,没有真实账号和后台数据。

<!doctype html>
<html lang="zh-CN">
<meta charset="utf-8">
<title>待办搜索练习</title>
<label>搜索待办 <input id="query" type="search"></label>
<ul id="tasks">
  <li>整理合同</li>
  <li>核对报表</li>
  <li>预约会议</li>
</ul>
<p id="empty" hidden>没有匹配项</p>
<script>
const query = document.querySelector('#query');
const rows = [...document.querySelectorAll('#tasks li')];
query.addEventListener('input', () => {
  const word = query.value.trim();
  for (const row of rows) {
    row.hidden = !row.textContent.includes(word);
  }
  document.querySelector('#empty').hidden =
    rows.some(row => !row.hidden);
});
</script>
</html>

在练习目录的一个终端启动静态服务,只绑定本机:

.\.venv\Scripts\python.exe -m http.server 8765 --bind 127.0.0.1 --directory site

另开浏览器访问 http://127.0.0.1:8765。手动输入“报表”,应只看到“核对报表”;输入“不存在”,应出现空结果提示;清空输入后应恢复三项。先写出正确行为,再让 AI 编写断言,否则自动化可能只证明页面能打开。

四、怎样给 Claude 一份可执行的测试要求

在 Claude Code 中说明本地服务已经运行,再使用下面的任务描述。这个步骤让 Skill 组织测试,而不是让模型凭空猜网页结构。

使用 webapp-testing 检查 http://127.0.0.1:8765。
只操作此本地练习,不访问外部网站,不修改页面代码。
先观察实际渲染的页面和标签,再生成 Python Playwright 测试。
检查:初始显示三项;搜索“报表”只显示匹配项;
搜索“不存在”显示空结果;清空后恢复三项。
保存截图与失败信息,不以截图代替断言,不自动改掉失败断言。

官方 Skill 提供先观察再操作的思路。对于这个静态小页面,页面加载后直接等待目标元素和断言即可;对于长期联网、流式内容或轮询页面,不应无限等待“网络完全空闲”,而应选择与任务有关的可见状态。

五、一份可检查的测试脚本

在练习目录新建 test_search.py。以下是与练习页面匹配的示例脚本;用于真实项目时,应根据实际 DOM 和标签调整,而不是把选择器照抄过去。

from pathlib import Path
from playwright.sync_api import sync_playwright, expect

Path("artifacts").mkdir(exist_ok=True)
with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    errors = []
    page.on("pageerror", lambda err: errors.append(str(err)))
    try:
        page.goto("http://127.0.0.1:8765")
        query = page.get_by_label("搜索待办")
        visible = page.locator("#tasks li:visible")
        expect(visible).to_have_count(3)
        query.fill("报表")
        expect(visible).to_have_text(["核对报表"])
        query.fill("不存在")
        expect(visible).to_have_count(0)
        expect(page.get_by_text("没有匹配项", exact=True)).to_be_visible()
        query.fill("")
        expect(visible).to_have_count(3)
        expect(page.get_by_text("没有匹配项", exact=True)).to_be_hidden()
        if errors:
            raise AssertionError("页面出现 JavaScript 异常")
        print("搜索、空结果与清空恢复检查通过")
    finally:
        page.screenshot(path="artifacts/search-final.png", full_page=True)
        Path("artifacts/page-errors.txt").write_text(
            "\n".join(errors), encoding="utf-8"
        )
        browser.close()

在第二个终端运行:

.\.venv\Scripts\python.exe test_search.py

合格结果应同时包含断言通过、截图文件和日志记录。截图只能辅助观察,不能代替文本匹配和可见性检查;日志为空也不能证明所有业务逻辑都正确。若测试在浏览器启动前就失败,应先排查环境,而不是期待截图一定生成。

六、需要自动启动服务时再用辅助脚本

第一次练习可以手动启动服务,更容易定位错误。熟悉后,先查看下载包中辅助脚本的帮助:

.\.venv\Scripts\python.exe .\webapp-testing\scripts\with_server.py --help

它支持 --server、--port 和测试命令,官方示例还展示了多个服务。使用时必须把服务命令、实际监听端口和测试地址对应起来。端口能连接只代表服务开始监听,不代表页面功能已经验收成功,仍需后续断言。

如果当前 8765 已有手动服务,不要再启动第二个占用相同端口的进程。先在原终端按 Ctrl+C 停止练习服务,再根据帮助组织自动启动命令。真实开发项目的启动命令取自它自己的 README,不把 npm run dev 当成所有项目都存在的通用命令。

网页测试按环境、服务、选择器、断言四层定位错误的检查示意

上图为原创排错示意。检查环境和地址后,再判断是否真的是页面缺陷。

七、失败时保留证据,不修改答案凑通过

  1. 找不到浏览器:确认安装 Playwright 与执行浏览器安装命令的是同一个虚拟环境;按提示补装所需浏览器及系统依赖。
  2. 连接拒绝或页面不对:检查服务终端、8765 端口和目录,避免测试到另一份旧项目。服务正常监听,也可能因目录错误显示文件列表而非练习页。
  3. 找不到元素:先检查真实标签、iframe 和渲染状态,再选择稳定定位器,不要直接增加随机等待时间或猜一个选择器。
  4. 断言失败:保存错误、截图和实际页面状态。若页面需求明确,不应删除失败步骤、放宽文本匹配或让 AI 悄悄修改页面来制造通过结果。

这次练习的交付物应为测试脚本、输入条件、检查清单、截图和错误记录。它证明的是指定环境下几个明确行为的结果,不是“全站无 bug”的保证。后续可把真实项目中最重要的搜索、筛选和表单路径逐个加入,保持每条测试有清楚的输入和预期。

来源与下载

页面下方的 Skill 下载入口提供本文固定提交的源码整理包。下载后先核对版本和文件内容;官方在线插件与离线源码包的版本可能不同,测试记录中应注明实际使用的版本。