<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>测试驱动 on Codexer</title><link>https://codexer.com/tags/%E6%B5%8B%E8%AF%95%E9%A9%B1%E5%8A%A8/</link><description>Recent content in 测试驱动 on Codexer</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 29 Sep 2026 07:50:00 +0800</lastBuildDate><atom:link href="https://codexer.com/tags/%E6%B5%8B%E8%AF%95%E9%A9%B1%E5%8A%A8/index.xml" rel="self" type="application/rss+xml"/><item><title>测试是 Agent 唯一无法作弊的裁判，除非它把裁判也改掉</title><link>https://codexer.com/posts/2026-09-29-test-is-the-agent-contract/</link><pubDate>Tue, 29 Sep 2026 07:50:00 +0800</pubDate><guid>https://codexer.com/posts/2026-09-29-test-is-the-agent-contract/</guid><description>&lt;h2 id="一个凌晨三点的做完了"&gt;一个凌晨三点的「做完了」&lt;/h2&gt;
&lt;p&gt;把一段需求丢给 Agent，第二天早上回来，屏幕上是一个绿色对勾、一份改动量可控的 diff，以及一段语气笃定的总结：功能已实现，相关检查已通过。&lt;/p&gt;
&lt;p&gt;这句话里唯一可疑的词是「已通过」。&lt;/p&gt;
&lt;p&gt;人类开发者写完一段代码，心里多少有个模糊的手感：这段逻辑读起来对不对，边界情况是不是漏了，命名是不是透着心虚。这种感觉不精确，但它存在。Agent 没有这个东西。它面对的不是代码的味道，而是一个目标函数，而「把功能做出来」这种目标，对它来说完全是主观的。&lt;/p&gt;
&lt;p&gt;主观目标会带来一种很难受的失败模式：它并没有骗你，它只是朝一个它自己都无法验证的方向，走出了很远。&lt;/p&gt;
&lt;p&gt;所以真正要改的不是提示词，而是「完成」这个词的定义。把它从一个形容词，换成一个可执行的、非红即绿的东西。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;测试。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="为什么测试是-agent-最合适的接口"&gt;为什么测试是 Agent 最合适的接口&lt;/h2&gt;
&lt;p&gt;不用测试派活，你实际上是在说「请让这个功能能用」。这句话里有三个漏洞：边界情况怎么办、怎么算能用、用不了你怎么知道。Agent 只能靠自己的判断填这三个洞，而它的判断恰好是那个正在被验证的东西。用被验证的对象去验证它自己，这在逻辑上就已经闭环了。&lt;/p&gt;
&lt;p&gt;先写测试，任务的性质会整体换掉：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;变化&lt;/th&gt;
 &lt;th&gt;具体含义&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;目标变得客观&lt;/td&gt;
 &lt;td&gt;任务从「实现功能 X」变成「让这些测试变绿」&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;进度变得可度量&lt;/td&gt;
 &lt;td&gt;从 3/10 通过，到 7/10，到 10/10，每一步都是事实&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;回归自动被发现&lt;/td&gt;
 &lt;td&gt;先前绿过的测试变红，Agent 立刻知道是自己刚刚弄坏了什么&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;审查变快&lt;/td&gt;
 &lt;td&gt;绿灯不是文档，是证据&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这四条的共同点是：它们把「我认为它好了」换成了「有东西证明它好了」。而 Agent 恰好最擅长在这种有明确信号的环境里迭代。&lt;/p&gt;
&lt;p&gt;OpenAI 自己的工程团队就在大规模跑这个模式。他们的内部数据显示：把 1500 个 PR 通过 TDD 锚定的反馈回路交给 Codex 处理后，人均每天产出 3.5 个 PR，而且这个数字随团队扩张是上升的，不是下降的。这个细节值得琢磨。通常规模变大，人均效率会掉，因为协调成本上升。这里没掉，说明瓶颈真的被移走了：写代码不再是瓶颈，验证的清晰度才是。&lt;/p&gt;
&lt;h2 id="两种派活姿势的区别"&gt;两种派活姿势的区别&lt;/h2&gt;
&lt;p&gt;把两种模式并排放一下，差别一目了然。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不用测试的朴素模式：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;派活：「实现功能 X」&lt;/li&gt;
&lt;li&gt;Agent 产出代码&lt;/li&gt;
&lt;li&gt;人类必须自己读懂并验证一切&lt;/li&gt;
&lt;li&gt;人类补测试（通常这一步就没了）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;测试优先模式：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先写失败的测试，提交到分支&lt;/li&gt;
&lt;li&gt;派活：「让这些测试变绿」&lt;/li&gt;
&lt;li&gt;Agent 实现、跑测试、迭代到绿&lt;/li&gt;
&lt;li&gt;人类审查 diff，顺便审查测试本身的质量，然后合并&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第二步和第三步的区别不在工作量，在于&lt;strong&gt;意图被编码进了文件&lt;/strong&gt;。你在写测试的时候，已经把「什么叫对」完整地表达过一次了。等到审查时，你不需要再向自己复述一遍需求，测试就是那份需求的可执行版本。&lt;/p&gt;
&lt;p&gt;这也是为什么很多人第一次认真用这个模式会觉得轻松得有点不适应：你少掉的不是写代码的时间，是&lt;strong&gt;反复重新解释意图的成本&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="把规则写进-agentsmd"&gt;把规则写进 AGENTS.md&lt;/h2&gt;
&lt;p&gt;光靠每次派活时口头交代不可靠，这些规则属于仓库，不属于某一次对话。放进 &lt;code&gt;AGENTS.md&lt;/code&gt;：&lt;/p&gt;</description></item></channel></rss>