代码没测试怎么改安全,我试过三条路
烧烤店那个小程序交付完之后,我盯着自己不到 20 行的代码想了很久:它一共卖了 ¥3000,但我没为它写过一个测试。真正让我头疼的是后面那些还在维护、我却答不上「代码没有测试怎么改比较安全」的项目。
我绕过三条路,最后留下的是一条最笨的。
一、代码没有测试怎么改比较安全:先把测试补上,再动手
听起来最正确,我做了一次就放弃了。
原因是补测试的成本,取决于代码本身的结构。而需要补测试的代码,通常结构正好是最难测的那种——依赖写死、逻辑和 IO 混在一起、函数几百行。
在没有测试的代码上补测试,本身就是一次重构。如果你只是想改一个小需求,这条路的时间成本大概率超过预期。
它的坑在于顺序:本来是为了改得安全才补测试,结果补测试的过程先引入了风险。为了安全做的事,本身不安全,这个逻辑就绕不通了。
二、第二条路:靠类型和静态检查兜底
第二条路温和得多:先不动代码,把编译器能帮你查的东西调到最严——空值检查、未使用变量、错误处理强制判断。
这条路确实抓到了东西,尤其是「错误被忽略了」这一类,改起来也不费劲。
但它的天花板很明显:编译器只能告诉你类型对不对,告不了你业务对不对。一个金额算反了、一个条件写反了,它一句话都不会说。
所以这条路的定位应该是补充,不是主力。它适合在改动前先扫一遍,把低级问题清掉。
三、第三条路:先建立「现在是对的」这个基准
第三条路是我最后留下来的,也是投入产出最高的一条。
动手改之前,我先做一件事:让现在这个版本的行为被记录下来。不要求写成标准测试,只要能在改动前后跑一遍,确认原来的行为没变。
形式可以是手工验证的固定步骤,也可以是几条最粗的检查,甚至只是一次完整的操作流程。关键不在于它多专业,在于它必须在你改之前就存在。
没有基准,你连「改坏了」都不知道,这才是最危险的。
基准的记录方式随你,写下来最好,能自动跑更好。核心要求只有一条:它必须是我改之前就存在的。
四、我实际改的时候会做的三件事
第一件,把要改的地方和它的调用方先找出来,确认影响范围;第二件,改动切成小块,每块改完立刻跑一次那个基准;第三件,留一份能回退的版本。
这三件事都不高级,但组合起来非常有效。安全感的来源从来不是测试数量,是每一步都可回退。
第二件事里那个「立刻跑一次」很关键,它把问题定位在很小的范围内。
五、为什么我不建议先大重构再改需求
试过的人大概都有体会:想先把烂代码理干净,再实现新需求,最后理到一半发现需求变了,两件事同时悬空。
我现在的顺序固定是:先让需求在现有结构里跑通,能验证了,再回头收拾结构。顺序反过来,你会在很长一段时间里没有一个能验证的版本。
六、什么情况下我会真的补测试
也不是完全不补。有两种情况我会认真补:一是这段逻辑会长期存在、反复被改;二是我已经在这段代码上犯过一次错。
测试不是写给人看的,是写给「下一次改这里的我」的。认得清这一点,代码没有测试怎么改比较安全的时机判断就很好做了。
常见问题
Q:代码没有测试怎么改比较安全?
A:先把当前版本的正常行为记录下来当基准,再小步修改、每步验证,并保留可回退的版本。这比先补一整套测试更快,也足够安全。
Q:老代码补测试值得吗?
A:看这段代码还会不会被改。会长期反复改的,值得补;即将被替换或只是偶尔碰一次的,用基准验证的方式更划算。
Q:没有测试就重构,是不是太冒险?
A:风险不在重构,在你无法判断改完是否等价。只要存在一个能在改动前后对比的行为基准,风险就大幅下降。
相关阅读
本文作者西米,37 岁程序员,一个人加五个 AI 员工在跑一家公司。踩过的坑和真实账本都写在公众号「西米分享」。
完整代码、踩坑清单与最新进展,都在公众号。
📱 关注公众号「西米分享」