关于 dogfood
Dogfood 是一项使用 browser_exec 对 Web 应用进行系统化探索式 QA 的技能。它引导测试人员规划测试范围、检查交互、收集证据、分类问题并生成结构化缺陷报告。
主要功能
- 01规划测试范围和页面覆盖
- 02测试交互与表单验证
- 03捕获截图和控制台错误
- 04分类并合并重复问题
- 05生成结构化 QA 报告
适用场景
- 01发布前探索测试 Web 应用
- 02测试表单和多步骤用户流程
- 03整理含证据的可复现问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nousresearch/ hermes-agent --skill dogfood安装后在 Claude Code 中输入/dogfood确认已加载。
附带文件references/issue-taxonomy.mdtemplates/dogfood-report-template.md
详细介绍
Dogfood:系统化 Web 应用 QA 测试
概述
此技能将指导你使用 browser_exec 对 Web 应用进行系统化的探索式 QA 测试。你将浏览应用、与各类元素交互、收集问题证据,并生成结构化的错误报告。
前提条件
- 必须启用
browser工具集(browser_exec)。browser_exec使用预先导入了辅助函数(new_tab、goto_url、wait_for_load、page_info、js、fill_input、click_at_xy、capture_screenshot、cdp)的 Python 环境运行;浏览器状态会在多次调用之间保留,但 Python 变量不会。 - 用户提供的目标 URL 和测试范围
输入
用户提供:
- 目标 URL — 测试入口
- 范围 — 要重点测试的区域/功能(或填写“完整站点”以进行全面测试)
- 输出目录(可选)— 保存截图和报告的位置(默认为
./dogfood-output)
工作流
遵循以下 5 个阶段的系统化工作流:
阶段 1:规划
- 创建输出目录结构:
{output_dir}/ ├── screenshots/ # Evidence screenshots └── report.md # Final report (generated in Phase 5) - 根据用户输入确定测试范围。
- 规划要测试的页面和功能,构建大致的站点地图:
- 落地页/主页
- 导航链接(页眉、页脚、侧边栏)
- 关键用户流程(注册、登录、搜索、结账等)
- 表单和交互元素
- 边缘情况(空状态、错误页面、404)
阶段 2:探索
将每一步的操作合并到一次 browser_exec 调用中。针对计划中的每个页面或功能:
-
安装控制台钩子后再导航。 在标签页上注册钩子,然后再导航,以便捕获页面加载期间抛出的错误:
# Open page with console-error capture HOOK = """window.__qa_errors = []; const _e = console.error; console.error = (...a) => { window.__qa_errors.push(a.map(String).join(' ')); _e(...a); }; addEventListener('error', e => window.__qa_errors.push('uncaught: ' + e.message)); addEventListener('unhandledrejection', e => window.__qa_errors.push('rejection: ' + String(e.reason)));""" new_tab('about:blank') # first call only: the hook binds to the current tab cdp('Page.addScriptToEvaluateOnNewDocument', source=HOOK) goto_url("https://example.com/page") wait_for_load() print(page_info()) print(js('window.__qa_errors || []'))在后续任何会执行导航的调用开始时,重新注册钩子。静默的 JS 错误是很有价值的发现。
-
读取页面结构 — 列出可见的交互元素及其视口中心点(需要角色/名称时,使用
cdp('Accessibility.getFullAXTree')并在 Python 中筛选):# List interactive elements print(js("""(() => [...document.querySelectorAll('a,button,input,select,textarea,[role=button]')] .filter(e => e.offsetParent).slice(0, 80).map((e, i) => { const r = e.getBoundingClientRect(); return {i, tag: e.tagName, text: (e.innerText || e.value || e.getAttribute('aria-label') || '').trim().slice(0, 60), id: e.id, name: e.name, x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2)}; }))()""")) -
进行页面视觉评估: 调用
capture_screenshot()并检查附带的图像,查看布局问题、损坏的元素或无障碍问题。如果你的模型无法查看图像,请将打印出的路径传给vision_analyze。 -
系统地测试交互元素:
- 点击按钮和链接:
js("document.querySelector('#submit').click()"),或使用步骤 2 中的中心点调用click_at_xy(x, y) - 填写表单:
fill_input('input[name=email]', 'test input') - 测试键盘导航:调用
cdp('Input.dispatchKeyEvent', type='keyDown', key='Tab', code='Tab', windowsVirtualKeyCode=9),然后调用对应的keyUp,再调用js('document.activeElement.outerHTML.slice(0, 200)')查看焦点落在何处;使用key='Enter'、code='Enter'、windowsVirtualKeyCode=13可按同样方式测试 - 滚动浏览内容:
js('window.scrollBy(0, 800)') - 返回:
js('history.back()'),然后调用wait_for_load() - 使用无效输入测试表单验证
- 测试提交空表单
- 点击按钮和链接:
-
每次交互后,在同一次调用中检查:
- 控制台错误:
print(js('window.__qa_errors || []')) - 视觉变化:调用
capture_screenshot()并与上一张截图比较 - 预期行为与实际行为(
page_info(),或使用js()读取相关元素)
- 控制台错误:
阶段 3:收集证据
对于发现的每个问题:
-
截取显示问题的屏幕截图:
capture_screenshot()会打印保存路径。将截图复制到{output_dir}/screenshots/,并使用描述性名称(例如issue-03-broken-login.png)——之后会在报告中引用该路径。 -
记录详情:
- 问题发生的 URL
- 复现步骤
- 预期行为
- 实际行为
- 控制台错误(如有)
- 截图路径
-
根据问题分类体系对问题进行分类(见
references/issue-taxonomy.md):- 严重程度:严重 / 高 / 中 / 低
- 类别:功能 / 视觉 / 无障碍 / 控制台 / 用户体验 / 内容
阶段 4:分类
- 检查所有已收集的问题。
- 去重——合并在不同位置表现为同一缺陷的问题。
- 为每个问题确定最终严重程度和类别。
- 按严重程度排序(Critical 优先,其次是 High、Medium、Low)。
- 按严重程度和类别统计问题数量,以便撰写执行摘要。
阶段 5:报告
使用 templates/dogfood-report-template.md 中的模板生成最终报告。
报告必须包含:
- 执行摘要,包含问题总数、严重程度分类统计和测试范围
- 每个问题的详情,包含:
- 问题编号和标题
- 严重程度和类别徽章
- 发现问题的 URL
- 问题描述
- 复现步骤
- 预期行为与实际行为
- 截图引用(内嵌图片请使用
MEDIA:<screenshot_path>) - 相关的控制台错误
- 所有问题的汇总表
- 测试备注——测试了什么、未测试什么,以及遇到的任何阻塞项
将报告保存到 {output_dir}/report.md。
工具参考
所有浏览器操作都通过 browser_exec 调用;以下是上文使用的辅助函数和惯用写法。
| 操作 | browser_exec 惯用写法 |
|---|---|
| 前往 URL | 调用一次 new_tab(url)(或在注册钩子前调用 new_tab('about:blank')),然后调用 goto_url(url);接着调用 wait_for_load() |
| 页面状态 | page_info() |
| DOM / 无障碍树 | 使用 js(...) 提取,或在 Python 中筛选 cdp('Accessibility.getFullAXTree') 的结果 |
| 点击 | js("document.querySelector(sel).click()") 或 click_at_xy(x, y) |
| 在输入框中输入 | fill_input(selector, text) |
| 滚动 | js('window.scrollBy(0, 800)') |
| 返回上一页 | js('history.back()') |
| 按键 | cdp('Input.dispatchKeyEvent', type='keyDown', key=..., code=..., windowsVirtualKeyCode=...) + keyUp |
| 截图 | capture_screenshot()(图片会附在结果中;仅支持文本的模型请对路径使用 vision_analyze) |
| JS 控制台错误 | 通过 cdp('Page.addScriptToEvaluateOnNewDocument', source=HOOK) 添加钩子,然后用 `js('window.__qa_errors |
提示
- 导航后以及进行重要交互后,始终读取
window.__qa_errors。 静默的 JS 错误是最有价值的发现之一。 - 将每个子流程批量放在一次
browser_exec调用中(导航、等待、提取、操作、检查错误)——这样往返更少,而且钩子会持续生效。 - 需要判断元素位置或 DOM 提取结果不明确时,请调用
capture_screenshot();click_at_xy使用元素列表中的中心坐标。 - 使用有效和无效输入进行测试——表单验证缺陷很常见。
- 滚动浏览长页面——折叠区域下方的内容可能存在渲染问题。
- 测试导航流程——端到端点击完成多步骤流程。
- 通过记录截图中可见的布局问题来检查响应式行为。
- 别忘了边界情况:空状态、超长文本、特殊字符、快速点击。
- 向用户报告截图时,请包含
MEDIA:<screenshot_path>,以便他们直接查看证据。