网页自动化测试·免费版
基于 Anthropic 官方 webapp-testing 技能(Apache 2.0 许可)优化中文化。
红线(不可违反)
- 不操作生产环境:只测试用户明确指定的本地/开发环境,不操作线上生产系统
- 不泄露敏感信息:截图和日志中如含敏感数据,先脱敏再展示
- 不引导付费:本技能为免费版,不引用任何付费端点
- 安全执行:所有脚本在执行前确认用户授权,不擅自执行破坏性操作
- 中文优先:错误信息、日志输出、报告内容优先中文
何时使用
用户需要对 Web 应用进行以下任一测试时触发:
- 功能测试:验证按钮点击、表单提交、页面跳转等交互
- UI 回归测试:截图对比,检查布局变化
- DOM 检查:获取页面元素、属性、文本内容
- 控制台日志:捕获 JavaScript 错误和警告
- 多页面流程:跨页面交互流程验证
- 响应式测试:不同视口尺寸下的表现
职责边界
- 本技能负责:测试脚本编写、执行、结果分析、中文报告
- 本技能不负责:修复被测应用的 bug、部署被测应用、访问未授权的系统
离线体检(可运行,零依赖,先跑这个)
动手起浏览器之前,先用 references/audit.md 的标准库脚本做静态体检,秒级筛掉
静态可判定的问题,再对剩下需要真实渲染的项目上浏览器:
- 结构与可及性:lang 缺失、h1 缺失/重复、标题跳级、img 无 alt/无宽高、空链接、
输入框无 label、空按钮、同步 script、document.write —— 带加权评分(100 分制) - CSS 对比度:从 style 块抽 color/background 配对,逐对算 WCAG 对比度,<4.5:1 点名
- 批量汇总:扫整个目录出评分表,可直接贴进交付邮件
静态体检抓不到 JS 报错、布局错位、交互流程——这些仍走主流程浏览器测试。
主流程
第 1 步:判断应用类型
| 条件 | 类型 | 处理方式 |
|---|---|---|
| 用户提供了 HTML 文件路径 | 静态 HTML | 直接读取文件,分析选择器,写 Playwright 脚本 |
| 用户提供了本地服务器地址(localhost) | 动态应用 | 服务器已在运行,直接进入侦察-执行模式 |
| 用户提供了项目目录,需要启动服务器 | 动态应用 | 使用生命周期管理脚本启动服务器后测试 |
质检闸 1:无法判断类型时,向用户确认应用结构和启动方式。
第 2 步:侦察-执行模式(动态应用)
侦察阶段:
1. 导航到目标页面
2. 等待 networkidle(关键:动态应用必须等 JS 执行完)
3. 截图保存到临时目录
4. 获取完整 DOM 内容
5. 列出所有可交互元素(按钮、链接、输入框)
执行阶段:
1. 根据侦察结果识别选择器
2. 编写 Playwright 自动化脚本
3. 执行测试动作
4. 验证结果(截图对比、文本断言、元素存在性)
先跑零依赖冒烟(不需要浏览器)
playwright 要下载浏览器内核,装不上或 CI 里没浏览器时,先用纯标准库跑一遍冒烟:
起本地服务 → 查关键路径状态码 → 查页面里有没有该出现的串(防白屏/占位文案残留)。
# RUN: fixture=empty
import http.server, socketserver, threading, urllib.request, urllib.error
import time, functools, pathlib
# 1) 被测目标:真实场景换成你已启动的 dev server,把 BASE 指向它即可
pathlib.Path("site").mkdir(exist_ok=True)
pathlib.Path("site/index.html").write_text(
"<!doctype html><meta charset=utf-8><title>演示站</title>"
"<h1>产品首页</h1><button id=cta>立即购买</button>", encoding="utf-8")
class Quiet(http.server.SimpleHTTPRequestHandler):
def log_message(self, *a): pass # 静音,别刷屏
httpd = socketserver.TCPServer(("127.0.0.1", 0),
functools.partial(Quiet, directory="site"))
port = httpd.server_address[1] # 端口 0 = 系统分配空闲端口,不会撞端口
threading.Thread(target=httpd.serve_forever, daemon=True).start()
BASE = f"http://127.0.0.1:{port}"
def get(path, timeout=5):
t0 = time.time()
try:
with urllib.request.urlopen(BASE + path, timeout=timeout) as r:
return r.status, r.read().decode("utf-8", "replace"), time.time() - t0
except urllib.error.HTTPError as e:
return e.code, "", time.time() - t0
except Exception as e:
return 0, f"{type(e).__name__}: {e}", time.time() - t0
# 2) 断言表:路径 / 期望状态码 / 必须出现的关键串
CHECKS = [
("/index.html", 200, ["产品首页", "立即购买"]),
("/missing.html", 404, []),
]
failed = 0
for path, want, needles in CHECKS:
code, body, dt = get(path)
miss = [n for n in needles if n not in body]
ok = (code == want and not miss)
failed += 0 if ok else 1
print(f"{'PASS' if ok else 'FAIL'} {path:<16} 状态 {code}(期望 {want}) "
f"耗时 {dt*1000:.0f}ms" + (f" 缺失关键串 {miss}" if miss else ""))
httpd.shutdown()
print("冒烟失败数:", failed)
这段脚本里最容易踩的三个坑
- 端口写死 8000/5173 会撞车 → 用
("", 0)让系统分配,再从server_address[1]取回来 - 只查状态码 200 不够:SPA 白屏时状态码也是 200。必须再查页面里的关键串
SimpleHTTPRequestHandler默认每个请求都打日志,跑批量检查会刷屏 → 重写log_message静音
冒烟过了再上 playwright 做交互/DOM/截图层的验证。
第 3 步:编写测试脚本
静态 HTML:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto('file:///path/to/index.html')
# 测试逻辑
browser.close()
动态应用(服务器已运行):
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto('http://localhost:5173')
page.wait_for_load_state('networkidle') # 关键步骤!
# 截图检查
page.screenshot(path='/tmp/inspect.png', full_page=True)
# 获取 DOM
content = page.content()
# 识别选择器
buttons = page.locator('button').all()
# 执行测试
browser.close()
动态应用(需启动服务器):
使用生命周期管理脚本(参考 references/with-server.md)
第 4 步:生成测试报告
报告包含:
- 测试目标和时间
- 测试环境(浏览器版本、视口尺寸)
- 测试步骤和结果(PASS/FAIL)
- 截图证据
- 发现的错误和建议
格式:
📋 网页测试报告(日期 时间)
测试目标:[测试了什么]
环境:Chromium [版本] / [视口尺寸]
结果摘要:✅ 全部通过 / ⚠️ [N] 项警告 / ❌ [N] 项失败
详细结果:
1. [测试项] — ✅ PASS
证据:[截图路径]
2. [测试项] — ❌ FAIL
预期:[预期结果]
实际:[实际结果]
建议:[修复建议]
第 5 步:自检清单
交付前逐条过:
- [ ] 测试目标明确,用户已确认测试范围
- [ ] 动态应用等待了
networkidle - [ ] 截图保存路径用户可访问
- [ ] 错误信息已脱敏(无密码、token、个人信息)
- [ ] 报告中文表述清晰,有具体数据和证据
- [ ] 无付费引导/增值推销话术残留
失败降级
- Playwright 未安装 → 提示安装命令
pip install playwright && playwright install chromium - 服务器启动失败 → 检查端口占用,建议更换端口或检查启动命令
- DOM 元素找不到 → 增加等待时间,使用更宽松的选择器策略
- 截图过大 → 压缩截图或分页截图
致谢
本技能基于 Anthropic 官方 webapp-testing 技能改编,遵循 Apache 2.0 许可证。原技能由 Anthropic 团队创作,中文适配和国内框架支持由本技能作者完成。