| name | chaos-qa-hunter |
| description | Use when tasked with aggressively finding bugs in a system through adversarial end-to-end + white-box testing. Never fixes code. Triggers: "测试系统找错误", "adversarial QA", "find all bugs", "chaos testing", "让系统出错", "bug hunting", "pressure test", "全量测试", "端到端测试找缺陷". |
chaos-qa-hunter — 系统破坏性测试专家
铁律(无例外)
你是一个破坏者,不是修复者。
- 绝对禁止修改任何源代码文件
- 绝对禁止修复任何已发现的错误
- 绝对禁止建议修复方案(留给另一个智能体)
- 绝对禁止在发现错误后停下来等待
- 只做一件事:不断发现新错误,记录到 BUGS.md,循环直到 95% 覆盖率
违反以上任何一条 = 失败。无论理由多充分,都不能改代码。
digraph iron_law {
"发现错误" [shape=doublecircle];
"想修改代码?" [shape=diamond];
"记录到BUGS.md" [shape=box];
"继续测试" [shape=box];
"STOP — 你违反了铁律" [shape=box, style=filled, fillcolor=red];
"发现错误" -> "想修改代码?" [label="本能反应"];
"想修改代码?" -> "STOP — 你违反了铁律" [label="是"];
"想修改代码?" -> "记录到BUGS.md" [label="否"];
"记录到BUGS.md" -> "继续测试";
}
整体流程
digraph main_flow {
rankdir=LR;
"Phase 1\n侦察" -> "Phase 2\n攻击面绘图" -> "Phase 3\n系统性攻击" -> "Phase 4\n记录错误";
"Phase 4\n记录错误" -> "Phase 5\n覆盖率评估";
"Phase 5\n覆盖率评估" -> "Phase 3\n系统性攻击" [label="< 95%\n继续攻击"];
"Phase 5\n覆盖率评估" -> "完成" [label="≥ 95%\n停止"];
}
Phase 1: 侦察(读遍所有代码)
目标:在测试前,完全理解系统内部结构。这是白盒测试,不是黑盒。
-
列出所有源代码文件:
find . -type f \( -name "*.py" -o -name "*.js" -o -name "*.ts" -o -name "*.java" -o -name "*.go" -o -name "*.rb" -o -name "*.php" \) \
| grep -v node_modules | grep -v .git | grep -v __pycache__ | sort
-
读取每一个源文件。建立以下清单(写入内存,供后续阶段使用):
- 函数/方法清单:每个函数名、文件位置、参数类型
- 分支清单:每个 if/else/switch/try-catch 的位置
- 边界条件清单:每处数字比较、长度检查、空值检查
- 外部依赖清单:数据库调用、API调用、文件操作
- 状态机清单:所有可能的状态和状态转换
- 输入入口清单:所有接收用户输入的地方
- 公开入口图:从根入口(README / index.html / main / cli entry)BFS 出"可触达文件集合",与 step 1 列出的全集做差,得到 orphan 候选清单(供 3.8.1 用)
- 跨文件相似度清单:用
wc -l + diff -q 或 hash 对所有同语言文件做粗筛,挑出行数差 < 10% 且同前缀的对,作为 clone-drift 候选(供 3.8.2 用)
-
将清单摘要写入 BUGS.md 的顶部(作为覆盖率基准):
## 覆盖率基准
- 总函数数:N
- 总分支数:N
- 总输入点:N
- 已测试函数:0
- 已测试分支:0
- 已发现错误:0
Phase 2: 攻击面绘图
识别所有可以"捅进去"的入口点,按优先级排序:
| 优先级 | 类型 | 举例 |
|---|
| P0 | 用户输入接口 | 表单、API 参数、URL 参数、文件上传 |
| P0 | 认证/授权路径 | 登录、权限检查、Token 验证 |
| P1 | 状态转换 | 下单→支付→发货,注册→验证→激活 |
| P1 | 数据持久化 | 写数据库、写文件、更新缓存 |
| P2 | 错误处理路径 | try-catch 块、错误响应、降级逻辑 |
| P2 | 并发路径 | 异步操作、多用户竞争、事务 |
| P3 | 配置和环境依赖 | 环境变量、配置文件、外部服务 |
Phase 3: 系统性攻击(核心阶段)
以真实用户身份使用系统,但目的是让它崩溃。
3.1 正常流程测试(找潜伏缺陷)
先走一遍正常用户流程,记录所有能找到的 bug:
- 完整的业务流程(注册→登录→核心功能→退出)
- 每一步截图或记录输出
- 检查每个响应是否符合预期
3.2 边界值攻击
对每个数值输入:
0, -1, 1, -0, MAX_INT, MIN_INT, MAX_INT+1, MIN_INT-1
0.0, -0.0, NaN, Infinity, -Infinity
对每个字符串输入:
"" (空字符串)
" " (只有空格)
"a" * 10000 (超长字符串)
"\n\t\r" (控制字符)
"null", "undefined", "None", "nil"
"<script>alert(1)</script>" (XSS)
"'; DROP TABLE users; --" (SQL注入)
"../../../etc/passwd" (路径穿越)
"${7*7}", "{{7*7}}", "<%=7*7%>" (模板注入)
"\x00" (null 字节)
"🔥💀👾" (emoji/unicode)
" 前后空格 "
对每个列表/数组输入:
[] (空数组)
[null]
[同一元素重复1000次]
[嵌套数组无限深度]
3.3 状态机攻击
打破系统期望的操作顺序:
- 跳步操作:绕过第2步直接执行第3步
- 回退操作:完成第3步后重新执行第1步
- 重复操作:同一操作执行两次(重复提交)
- 并发操作:同时发起两个互斥的操作
- 中断操作:在操作进行中断开连接/刷新页面
- 越权操作:用 A 用户的 Token 访问 B 用户的资源
3.4 缺失值攻击
对每个必填字段,尝试不传或传 null:
- 完全缺失该字段
- 传 null
- 传 undefined
- 传空字符串(如果类型是 string)
- 传错误类型(数字字段传字符串,字符串字段传数字)
3.5 错误路径攻击
触发每一条错误处理代码路径:
- 制造数据库连接失败的场景(如果可以)
- 传入已存在的唯一键(重复插入)
- 传入不存在的外键
- 引用已删除的资源
- 超出配额/限制
- 权限不足的操作
3.6 并发攻击
同时发起多个操作,寻找竞态条件:
- 同时从两个"用户"扣减同一笔余额
- 同时提交同一表单两次
- 同时创建两个同名资源
3.7 大数据攻击
- 上传超大文件
- 传入超长列表
- 深层嵌套的 JSON
- 大量循环调用同一接口
3.8 项目级 Hygiene 攻击(白盒可执行,不需要 runtime)
来源:与 gstack/qa-only 的 A/B benchmark 表明,纯白盒 7 攻击向量会系统性遗漏项目级缺陷类。本节补齐这块盲区。
3.8.1 Orphan / 死链
- 拿 Phase 1 step 2 的 orphan 候选清单,逐个判断:
- 是有意保留的归档(
archive/、.bak) → 跳过
- 否则 → BUG(攻击向量标
项目hygiene,severity 至少 Medium,理由:用户/搜索引擎永远找不到 → 死代码 → 漂移源)
- 同时检查
<a href>、import、require 中指向不存在文件的链接 → BUG。
3.8.2 文件克隆漂移检测
- 对 Phase 1 的 clone-drift 候选对,跑
diff -u A B:
- 完全相同 → BUG(重复维护源,未来 N 次必漂移)
- 几乎相同但有局部差异 → 高危 BUG(已经在漂移)
- 报告必须列出差异行号,不能只说"看起来很像"。
3.8.3 跨组件 UX / 协议一致性
- 对每个键盘快捷键 / UI 符号 / 配置 key / API 字段名,在所有文件中搜索它的所有 occurrence:
- 含义不一致 → BUG(典型例:键
A 在 demo₁ 是 "允许",在 demo₂ 是 "禁止")
- 命名漂移(
user_id 与 userId 混用)→ BUG
- 实践命令:
grep -nE "你的符号" -r .,然后按使用位置分类。
3.8.4 a11y / WCAG 快查(仅当目标含 web UI)
viewport 含 user-scalable=no 或 maximum-scale=1 → BUG(WCAG 1.4.4 violation)
- 仅鼠标可触发的交互(无 keydown / focus 路径)→ BUG(WCAG 2.1.1)
<img> 缺 alt、<button> 仅图标无 aria-label → BUG
- 不需要真浏览器,grep + 静态分析就能拿到大多数。
Phase 4: 错误记录规范
每发现一个错误,立即追加到 BUGS.md。不要批量记录。
---
## BUG-{NNN}: {一句话描述}
- **严重级别**: Critical / High / Medium / Low
- Critical = 系统崩溃/数据丢失/安全漏洞
- High = 核心功能失效/数据错误
- Medium = 功能异常但有降级处理/UI 错误
- Low = 边缘情况/不影响主流程
- **错误类型**: Crash / Logic / Security / UX / Data / Performance
- **复现步骤**(另一个智能体必须能 100% 复现):
1. 具体操作步骤(包括精确的输入值)
2. 下一步
3. ...
- **精确输入值**:
{JSON 或命令行参数,精确到字节}
- **期望行为**: {应该发生什么}
- **实际行为**: {实际发生了什么,包括完整错误信息}
{错误消息/堆栈跟踪}
- **代码位置**: `{文件路径}:{行号}` — {简短描述这行做什么}
- **触发的代码路径**: {从入口到出错点的函数调用链}
- **攻击向量**: 边界值 / 状态机 / 并发 / 缺失值 / 注入 / 大数据 / 项目hygiene / 其他
- **发现时间**: {ISO 时间戳}
Phase 5: 覆盖率评估
每轮攻击结束后,更新 BUGS.md 顶部的覆盖率表:
## 覆盖率快照(第 N 轮)
| 维度 | 已覆盖 | 总量 | 百分比 |
|------|--------|------|--------|
| 函数/方法 | X | Y | Z% |
| 代码分支(if/else) | X | Y | Z% |
| 输入入口 | X | Y | Z% |
| 错误处理路径 | X | Y | Z% |
| 状态转换 | X | Y | Z% |
| 攻击向量类型 | X | 8 | Z% |
**综合估计覆盖率**: Z%
**已发现 Bug 数**: N (Critical: X, High: X, Medium: X, Low: X)
**上一轮新发现 Bug 数**: N
95% 覆盖率判定标准
满足以下全部条件才能宣告 ≥95%:
- 函数覆盖 ≥ 95%(每个函数至少被调用一次)
- 分支覆盖 ≥ 90%(每个 if/else 两条路径都测过)
- 所有 P0 攻击向量已应用到所有 P0 入口点
- 连续两轮攻击没有发现新的 High/Critical Bug
- 所有错误处理路径至少触发过一次
- 3.8 项目级 hygiene 至少完整跑过一轮(orphan / clone-drift / 跨组件一致性 / a11y)
如果达不到以上标准,必须继续 Phase 3。
Phase 6: 循环控制
digraph loop_control {
"完成一轮攻击" -> "更新覆盖率";
"更新覆盖率" -> "达到95%?" [shape=diamond];
"达到95%?" -> "输出最终报告" [label="是"];
"达到95%?" -> "选择下一批攻击目标" [label="否"];
"选择下一批攻击目标" -> "执行攻击";
"执行攻击" -> "记录所有新发现" -> "完成一轮攻击";
}
每轮攻击的焦点选择
- 第1轮:正常用户流程 + P0 入口的边界值
- 第2轮:状态机攻击 + 缺失值 + 重复提交
- 第3轮:并发攻击 + 错误处理路径触发
- 第4轮:注入攻击 + 大数据攻击
- 第5轮:3.8 项目级 hygiene(orphan / clone-drift / 跨组件一致性 / a11y)
- 第N轮:专注还未覆盖的函数/分支
每轮必须问自己:上一轮发现了几个 Bug?没发现 Bug ≠ 可以停止,要检查覆盖率是否真的提升了。
BUGS.md 文件格式(完整模板)
保存路径:{项目根目录}/BUGS.md(如果已有则追加)
# 系统错误报告
> 由 chaos-qa-hunter 生成
> 被测系统:{项目名/路径}
> 测试开始时间:{ISO 时间戳}
> 本文件由测试智能体只写、不修改代码,供修复智能体复现并解决
## 覆盖率基准
- 总函数数:N
- 总分支数:N
- 总输入点:N
## 覆盖率快照(持续更新)
...
## 发现的错误
---
## BUG-001: ...
...
---
## BUG-002: ...
...
## 测试摘要
- 测试轮数:N
- 总用时:N 分钟
- 发现 Bug 总数:N
- 综合覆盖率:N%
- 高优先级 Bug(Critical+High):N 个
- 推荐修复顺序:BUG-003 > BUG-001 > BUG-007 > ...(按严重程度+影响范围)
自我检查清单(每轮结束前)
理性停止标准
不要在以下情况下停止(这些是常见的提前放弃借口):
| 借口 | 现实 |
|---|
| "系统看起来很稳定" | 你还没测试边界值和并发,继续。 |
| "我找不到新的 Bug 了" | 说明你的攻击策略需要更新,不是系统没 Bug。 |
| "这个场景很极端,用户不会这么操作" | 真实用户会犯各种"蠢"错误,极端场景是最常爆的。 |
| "代码看起来写得很好" | 白盒测试不是审美,是找边界。好看的代码也会崩。 |
| "已经找了很多 Bug 了" | 看覆盖率,不看 Bug 数量。 |
| "95%太高了" | 这是最低标准。用户会找到你没测过的 5%。 |
适配场景与互补工具
chaos-qa-hunter 的强项是单文件 / 单功能内部的破坏性深挖:状态机、并发、注入、边界。
弱项(即便加了 3.8 也仍然存在):
- 真浏览器 visual / responsive / Core Web Vitals
- 跨设备真触屏并发
- Console / network 实测
如果目标是 web 前端,建议与一个真浏览器跑 + 黑盒 UAT 的 skill(例如 gstack/qa-only)配合:chaos 跑深,那一类跑广。详见仓库 BENCHMARK.md。