4万行无测试代码接手经验:先用AI代理描述代码实际行为(包括看似bug可能是有意为之的部分),再基于真实行为补测试,避免将假设编码进测试。强调文档优先于测试。
四万行代码。零测试。原作者已离职。产品还在持续堆需求。
显而易见的选择是开始写测试。我先做了另一件事,如果重来一次,我还会这样做。
在知道当前行为是什么之前,你写不出有意义的测试——不是「应该怎样」,而是「实际上怎样」。
基于假设写测试,你就是在把你的假设编码进去。然后一次重构「通过」了,实际上却破坏了真东西,因为你的测试断言的是你想象中的行为,而不是用户依赖的行为。
遗留系统中充满了看起来像 bug 却是承重结构的行为。下游有人在依赖它。
我让 Agent 阅读关键路径,写出代码当前在做什么——包括那些看起来不对但可能是故意为之的部分。
Read the order processing path. Document actual current behavior,
including edge cases and anything that looks like a bug but may
be deliberate. Don't suggest changes. Describe only.
最后那条指令很重要。没有它,你会得到一份重构提案而不是描述,你就无法根据提案来写测试。
四万行塞不进一次会话,就算能塞进去,随着窗口填满,准确率也会下降。
分六批,每批一个模块:
子 Agent 读取模块,返回摘要
摘要汇入快照文档
子 Agent 步骤是关键——那些文件进入它的窗口,而不是我的。我的主线程累积了六份摘要,而不是四万行。
花了大约一周。没有交付任何功能。感觉毫无产出,但那却是整个项目最高效的一周。
有了快照,写测试就快了:照着文档,一个一个 case 来。
更重要的是,我现在可以对这些行为分类了。这个是有意为之,保留。这个是 bug 但有东西依赖它,保留并提 issue。这个是没人用的 bug,修复它。
没有这个「刻画」步骤,这种分类是不可能的。这才是那一周真正的产出。
我只覆盖了关键路径。不追求覆盖率——而是织一张足够密的网,让后续的改动能自动验证,而不是靠我读 diff。
一旦关键路径被覆盖,Agent 就能自己形成闭环:写,运行,读失败,修复,重复。
没有这张网,Agent 就停在「看起来完成了」,你就变成了验证环节。在一个陌生的四万行代码库上,这是个糟糕的处境——你是房间里最不适合发现回归问题的人。
那一周的「刻画」消耗是我平时正常使用的三到四倍,基本上都花在阅读阶段。
这就是一般规律:理解比生成更费 token。我审计了一年的日志,大约一半的用量是在理解代码,而不是写代码。接手一个遗留系统就是把这种比例放大了集中呈现。
它恰好是月度套餐最处理不了的那种峰值——一周密集使用,然后恢复正常。我保持一个低基准,在这种时期通过 Asale 补充,这是一个将未使用的订阅容量路由给需要它的人的市场,按每百万 token 计价。
注意事项:请求会通过另一个用户的客户端转发,所以有效载荷在该跳点是可见的。没有端到端加密,他们主页上写明了。那个项目是内部的,所以我用了公司账户——个人设置是用来做开源和 side project 的。值得在迁移中途之前就把这个边界定好。
有人找到过比写散文快照更好的刻画方法吗?验收测试看起来是个方向,但我没在这么大体量上试过。
你可以考虑屏蔽此人和/或举报滥用