mcpField
A
agentic-tdd

agentic-tdd

github.com/reticlehq测试与质量1.3k250 次安装今天更新
代码仓库

关于 agentic-tdd

这是用于 Reticle 的技能,将红—绿—重构 TDD 用于运行中的应用。它要求先定义操作预期结果,并可保存流程用于回归检查。

主要功能

  1. 01操作前断言预期结果
  2. 02检查信号、状态、网络和元素
  3. 03实现后重跑不变的断言
  4. 04保存流程以供回归复用

适用场景

  1. 01在实现功能前编写测试
  2. 02验证保持行为不变的重构
  3. 03将端到端流程转为回归检查

MCP 相关

Reticle 通过 MCP 提供此技能使用的交互、断言、录制和验证工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/reticlehq/reticle --skill agentic-tdd

安装后在 Claude Code 中输入/agentic-tdd确认已加载。

详细介绍

红、绿、重构:针对运行中的应用

单元测试驱动各个单元。它们无法说明“点击 Deploy 后会向 /api/deploy 发送请求、将 store 切换到 deploying,并显示横幅”:只有整个应用运行时,才会出现这种结果。因此,开发循环恰好在最有意思的 bug 出现时停滞,Agent 只能退而求其次,编写代码并寄希望于一切顺利。

这里将同样的纪律提升到更高一层,使用 Reticle 驱动真实应用。还没设置?请按照 reticle 技能操作:它会安装 Reticle,在 init 修改应用文件前征求用户同意,并验证一个流程。

为什么这是 TDD,而不只是事后测试

测试优先的全部价值在于:你尚不知道答案时,就写下预期。看到结果后再写预期,总能调整到与实际情况一致,而 Agent 尤其擅长这种调整。它总能找到一种解读结果的方式,让刚写出的代码看起来是正确的。

reticle_act_and_wait({ ref, action, until }) 在结构上确保了顺序:until 是 action 的参数,因此会在 action 执行前明确写出其结果。这就是真正无法造假的红绿循环。

1. RED:写下预期,看它失败

编写功能前,先说明应用必须实现什么:

reticle_act_and_wait({ sessionId, ref, action: "click", until: { kind: "allOf", predicates: [
  { kind: "net",     method: "POST", urlContains: "/api/deploy", status: 200 },
  { kind: "signal",  name: "deploy:started" },
  { kind: "element", query: { testid: "deploy-banner" } },
  { kind: "console", level: "error", absent: true },
]}})

这里需要 verified: "no"。**没亲眼看到的红灯,就不是可信的测试。**如果你还没写任何代码,它就返回 yes,说明预期没有针对这次改动写得足够具体。继续收紧预期,直到它因正确的原因而失败。

verified: "unknown" 不代表红灯。这表示 Reticle 无法判断,因此循环完全没有信号。编写代码前先修复这一点,通常只需明确指出应用实际能够产生的结果。

2. GREEN:实现功能,直到同一个调用通过

编写能让预期成立的最小改动,然后重新运行同一个调用,不做任何改动。最后几个字体现了纪律:修改谓词来匹配已实现的内容,会把 TDD 变成事后解说。如果断言必须修改,请明确说明原先的预期为什么有误。

如果结果为 unknown / unsettled,优先重新断言,而不是重新驱动:reticle_assert({ predicate, since, timeout_ms: 8000 })。重新驱动会重复已经发生过的副作用。

3. REFACTOR:让预期成为安全网

现在可以自由修改实现并重新运行。谓词绑定的是行为(请求、信号、状态路径),而不是标记,因此只要重构保留了行为,测试就会继续通过;而基于 DOM 的测试则可能无缘无故地失败。

4. 在下一次改动中继续这个循环

值得优先编写测试的流程,也值得永远重复运行。保存一次即可:

reticle_run({ tool: "reticle_record", sessionId, args: { action: "start", name: "deploy" } })
// drive the journey with reticle_act_and_wait, as in step 1
reticle_run({ tool: "reticle_record", sessionId, args: { action: "stop", name: "deploy" } })
reticle_run({ tool: "reticle_flow_save", sessionId, args: { flowName: "deploy" } })
reticle_run({ tool: "reticle_verify", sessionId, args: { action: "flows" } })   // every saved flow, no model per flow

这样,红绿循环就会变成一套无需手写的回归测试。

应断言的内容,按可靠性排序

  1. 应用自行发出的信号({ kind: "signal" }):应用用自己的语言宣告成功。这是最可靠的选择。
  2. 状态(reticle_look { action: "state" }):应用的认知。可捕捉 UI 已变化而 store 未变化的情况。
  3. 网络:请求、方法和状态码。可捕捉用 mock 代替真实请求的情况。
  4. 元素出现:必要,但永远不充分。任何内容都可能被渲染出来。
  5. 没有控制台错误:始终要纳入检查,但绝不能只依赖它。只检查“没有错误”的谓词,在什么都没连接的控件上也会通过。

诚实

**绝不要为了让结果变绿而放宽检查。**在这个循环中,这不是小问题:它会让循环倒着运行,最终得到一套全绿的测试,却无法证明功能正常。


谓词参考:curl https://docs.reticle.sh/predicates.md。其他所有内容:curl https://docs.reticle.sh/llms.txt。

评论

支持 Markdown