agentleFS
Suge8Suge8/friedbun/skills/development/better-test/SKILL.md

better-test

Skill12 starsChanged 6 days agoMITView on GitHub

写、改、删、审计测试时使用:什么测试值得留、端到端测试写法、DELETE/REWRITE/KEEP 判决。

The file

Files
SKILL.md

Better Test

测试是负债。agent 自己写的单元、集成测试只复述实现:测试和代码出自同一份理解,不比实现更准;实测不提高正确率,只增加时间和费用。持久测试只有两种来源:用户给出或认可的用例,和覆盖关键用户流程的端到端测试。

只走一个分支:

  1. 用户要求测试、工单给了用例,或关键用户流程确需新增端到端测试 → 写测试。
  2. 审计或清理既有测试 → 清理与审计。

价值门

判既有测试和写新测试共用这一道门,六条全部成立才留:

  1. 有来源:保护的行为来自用户的需求、用例、bug 报告、公开合同或规格示例,不是 agent 对实现的理解。
  2. 失败有意义:一种可信回归会让它失败,且失败对应调用方或用户可见的问题。
  3. 期望值独立:期望值来自已知字面值、规格或示例,有可能与实现结果不一致。
  4. 稳定接缝:经公开接口或稳定 seam 观察,不依赖只为测试存在的生产导出、flag、wrapper 或注入点。
  5. 抗重构:行为不变的内部重构、无关文案或布局调整后仍然通过。
  6. 唯一 owner:该合同只在最低的可靠边界证明一次,且没有被现有测试、类型系统、编译器或 lint 等价保证。

反模式

判断时按类对照;正则或文本命中只是线索,读完测试和被测代码才下结论。

  • 同义反复:按实现的算法重算期望值;断言声明等于自身;mock 返回什么就断言什么;期望值由被测 helper 或 renderer 自己产出。
  • 变更探测器:扫源码、import、标识符或字符串;数导出、路由、元素或清单行数;快照生成的 markup、组件树或 class 串;断言私有协作者、调用次数或调用形状。
  • 重复:同一场景在它穿过的每一层都重放一遍;近乎相同的用例(合并成表驱动);已被类型或编译保证的检查。
  • 空洞:没有断言或只证明"没崩";只测 getter、常量或框架能渲染。
  • 虚假信号:负向对照因无关原因通过(另一个守卫先拒绝、生产路径根本到不了);fixture 替被测方产出本该由它产生的结果;测试名承诺的比输入实际覆盖的多。
  • 测试专用生产接缝:只有测试调用的导出、全局、wrapper、flag,以及只被测试调用的死代码。
  • 外观当行为:尺寸、比例、坐标、computed style、布局 class、scrollWidth、挂载行数是外观证据,不是行为。视口只提供场景,断言落在用户任务完成上(移动端能找到并操作某个按钮)。用 role、可访问名、label 定位控件;只有措辞本身是需求时才断言文案。焦点和禁用态只在它就是交互合同时测(聚焦首个无效字段、对话框关闭后焦点归还);归一化矩阵放纯函数测试,组件层留一条代表用例。截图断言只在项目明确采用视觉回归时入套件。

像实现但必须保留:公开 API、协议与序列化字节、配置、迁移、存储格式、安全、默认值、跨语言生成物、架构约束——它们本身就是独立合同,满足价值门第 1 条。顺序可被观察时的调用顺序、以最低成本守住用户可见键名或路径的源码检查同理。

写测试

  1. 从需求、bug 报告或公开合同提取用例;工单或用户给的用例原样采用。已有依据直接执行,只有预期行为不明确且影响实现时才请用户拍板。
  2. 写成端到端测试:从用户真实入口(页面、CLI、公开 API)完成任务并断言结果;只 mock 付费或不可控的外部服务。
  3. 见红:每条新测试亲眼看到它因预期原因失败一次——功能尚未实现,或临时破坏被测实现(不是改断言)后再精确还原。从没红过的测试只证明了 mock。
  4. 一条用例一个用户任务;固定 seed、时钟和网络,用条件等待代替 sleep;不留 skip、僵尸进程或生成物。

完成标准:每条新增测试都有可追溯的需求或合同来源、过价值门且见过红。

清理与审计

范围与授权:范围按用户请求钉死——diff、路径、模块或全仓;全仓只在用户明确要求时做。"审计""看看""找找"是只读,交报告为止;"清理""删掉""精简"授权在范围内直接改。

分工:每条判决要读的东西多,范围跨 3 个以上模块时按 fan-out 中档分两波;全仓清理或用户要求仔细时用高档。

  • 按生产 owner 模块切片,每片带该模块的测试文件。多个模块共用的支撑代码(fixture、helper、全局 setup)不分给工人,由编排者最后处理,保持每个文件一个写者。
  • 第一波只读:与编排者同级的实现角色逐条判决,格式同下文报告,另交跨片线索——疑似与别片重复证明的合同(测试名、合同一句话、位置),没有写"无"。
  • 收口:同一合同跨片重复时保留最低可靠边界上的那条,其余改判 DELETE 并补证据;抽查每片的 KEEP 举证和 DELETE 证据,不全的退回。高档时 DELETE 另派不同模型的子代理独立复判,两份一致才删,不一致记为未定。审计到此合并报告。
  • 第二波(清理):原工人(或附定稿判决的新工人)只改片内文件并跑片内最窄验证;编排者最后删共享支撑代码和跨片的测试专用接缝,跑受影响验证。

逐条判决,不按文件。判之前读完测试全文、被测生产 owner、它的调用方、重叠测试、相关 git 历史,以及项目自己的测试规则。

  • KEEP:价值门六条逐条举证全部成立。
  • REWRITE:测试里有一个过门的合同,但现写法不过。只保留证明该合同所需的准备、动作和断言,不沿用旧测试的体量、断言数或层级。
  • DELETE:不过门(agent 写的、只复述实现的单元与集成测试通常落在这里),且写全三项证据——它实际能抓住什么失败;该行为别处更强的证明,或为什么不需要证明;它或它依赖的测试专用接缝当初为何存在。
  • 未定:KEEP 举证不全,DELETE 证据也不全。写进报告,不动。

既有测试在基线上就失败时,当作可能的产品缺陷先定位根因,不删。

执行:删测试时一并删掉它独占的测试专用生产接缝与死代码,以及因此失效的 fixture、helper、快照和 setup。为保住测试而改生产行为、降低断言、关闭规则、调低覆盖率阈值都不是解法;覆盖率或数量门槛挡住合理删除时,报告冲突。改完跑最窄受影响验证和仓库要求的门。

报告:写明是审计建议还是已完成的清理。逐条列出 DELETE / REWRITE / KEEP / 未定 的位置与理由;KEEP 和 REWRITE 附六条举证,DELETE 附三项证据;列出删掉的生产接缝、跑过的命令与结果,生产代码与测试代码的行数变化分开写。

完成标准:范围内每个候选都有判决,留下的测试全部过门,没有残留的死测试支撑代码,验证结果已知。

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.