← 返回文章列表

生产代码已死,测试代码万岁

2026年3月7日 · 5 min read

十二年前,DHH写了一篇"TDD is dead. Long live testing."(TDD已死,测试万岁),整个互联网炸了锅。他说对了——但说早了。2026年,不只是TDD死了。死的是整个"生产代码是你写的最有价值的东西"这个概念。

我每天都在用Claude Code、Codex和Gemini构建和发布产品。几十个项目,几千条AI辅助prompt。所有这些经历中最清晰的一个洞察是:最重要的代码不再是用户看到的那些代码,而是确保用户看到的代码真的能用的那些代码。

测试代码,就是新的生产代码。


从零到一,从未如此简单

说句实话。生成逻辑正在变成一种commodity(大众商品)。

去年,我一个人发布了一整套屏幕录制引擎、UI框架和导出管线。以前需要五个人一个sprint(迭代周期)的功能,现在我一个下午就搞定。Claude Code写实现,Gemini审架构,Codex抓边界情况。我负责调度。代码就这么出来了。

这不是在炫耀。这就是普通的周二。越来越多的开发者只要花200美元/月买AI订阅、并且能清晰定义问题,就能做到类似的事。一个十几岁的小孩在卧室里就能周末搭出一个SaaS的骨架。一个非技术创始人在种子轮关闭之前就能prompt出一个能用的原型。

从零到一的成本从未如此之低。从一到一百也在加速。

瓶颈正在转移。以前是"你能不能做出来",现在越来越变成"它到底能不能用——以及当你改了什么之后,它还能不能继续用?"


生产代码不再是你的护城河

这是让人焦虑的部分,而且应该焦虑。

如果任何人都能以接近零的边际成本生成生产代码,那生产代码就不再是竞争优势。它只是入场券。就像2005年有个网站一样——你需要一个,但有一个并不让你特别。

那护城河是什么?

我认为答案是稳定性。可靠性。当你发布时,你确信它能用。当你重构时,没有东西在暗处坏掉。当你的AI在30秒内生成500行代码时,你知道——不是希望,是知道——它做了它应该做的事。

这种信心主要来自一个地方:测试代码。

没错,有一整个更广泛的验证栈——类型系统、linter、静态分析、staging环境、可观测性、feature flags。这些都重要。但测试是可执行的规格说明。它们用机器可验证的格式编码了意图。其他工具检查的是形式。测试检查的是行为

有一个类比我觉得很有启发性。想想AI自身是怎么改进的。在强化学习中,循环是:生成输出,根据标准评估,反馈结果。RLHF中的奖励模型并不完全等同于测试套件——但它扮演了类似的角色。它是驱动收敛的评估信号。没有它,模型只会生成看起来像样的垃圾。

软件中的杠杆在以同样的方式转移——从创建行为的代码转向验证行为的代码。从输出到验证器。从生产到证明。


把50%的token花在测试上。我是认真的。

这是我真实的、有立场的观点:如果你在用AI构建软件,你应该至少花一半的时间和token写测试。不是生产逻辑。是测试。

我知道这听起来极端。让我解释为什么我这样想。

当AI写你的生产代码时,只有两种可能的结果。要么代码能用,要么不能用。如果不能用而你没有测试,你和用户同时发现问题。那是灾难。

如果不能用但你有测试,你在几秒内就发现了。这就是五分钟修复和五级火警的区别。

但不止于此。测试就是规格说明。当你先写测试——或者和prompt同时写——你是在把你的意图编码成机器可验证的格式。你不是在告诉AI"给我做个登录系统",而是"给我做个登录系统,要拒绝8位以下的密码,5次尝试后限流,并处理Unicode用户名"。测试就是规格说明,规格说明就是测试。

在AI加速的世界里,代码生成的速度远超任何人类能够阅读的速度,测试是你的产品和混乱之间唯一的屏障。

我亲眼见过这件事出错。上个季度,我用Claude Code重构了ScreenKite的导出定价逻辑。AI把模块重写得很干净——所有旧的行为都保留了,至少看起来是这样。一切编译通过。App运行正常。但四舍五入策略从round half up变成了round half even。差别:可能每次一两分钱。六周后才有用户发现发票和收据对不上。一个断言export_price(9.995) == 9.99的测试就能在几秒内捕获这个问题。

这不是假设。这是我的代码库。我也听到其他团队发布无测试AI生成代码时遇到了类似的故事。

测试代码是隐形的。用户永远看不到。投资人从不问。它不会让demo更好看。这正是它被低估的原因。也正是认真对待它的团队会赢的原因。


测试作为反馈循环

前面的强化学习类比不只是哲学思考——它对你如何使用AI编程工具有实际的影响。

你的AI agent生成代码,你的测试套件评估它。反馈循环——红色测试、修复、绿色测试——其功能类似于强化学习中的奖励信号。不是完全相同的机制,但在结构上是类似的:都是针对评估标准的迭代优化。

如果你的测试套件太薄,你的AI agent就是在盲飞。它生成了看起来对的东西。你没有信号告诉你它是否真的对。所以你发布然后祈祷。

如果你的测试套件足够全面,AI就有了清晰的目标函数。它可以迭代、自我修正、收敛。测试不只是在抓bug——它们在引导生成过程。

这就是为什么我说测试代码是你写的最重要的代码。它不只是安全网。它是制导系统。

你可能会反驳:"但大语言模型永远学不会我的具体项目。它们没有本地记忆。"我以前也这么想。现在我认为这是错的。

你的代码库不只是代码。它是记忆。你写的每一个测试都在教AI什么是你的项目中正确的行为。每一个文档文件、每一个AGENTS.md、每一个架构决策记录——这些都是跨会话存活的持久化本地记忆。当你更新项目的文档和测试套件时,你不只是在维护软件。你是在训练一个本地的奖励模型。你是在把你的策略、你的边界情况、你用血泪换来的教训,编码成AI能够真正使用的格式。

搞明白这件事的团队,他们的AI agent将真正理解他们的代码库——不是因为模型变聪明了,而是因为本地上下文变丰富了。测试、文档和记忆文件,是这个三脚架的三条腿。


呼吁重新平衡

我不是说我有所有的答案。这是我个人的观点,来自每天用AI构建真实产品的经验。欢迎批评指正——我是认真的。

但这是我的信念:

我们正在进入一个生成代码几乎零成本的时代。维护代码才是一切代价所在。而在大规模维护代码最可靠的方式——尤其是那些你没有手写的代码、不断变化的代码、三个不同AI模型碰过的代码——就是拥有一个测试套件,告诉你什么仍然是对的,什么已经不是了。类型系统有用。Linter有用。Staging有用。但测试是核心的可执行契约。

未来会脱颖而出的开发者不是prompt最快的人。他们是代码在六个月后还能用的人。而秘密简单得令人尴尬:把你的token花在测试上。无聊的、看不见的、关键的测试。

生产代码已死。测试代码万岁。


我是Mike,在Edmonton和老婆一起经营micro-company(微型公司),每天用AI编程、公开构建。关注我 @RealMikeChong