案例4 · 用 AI 给遗留代码补单测,覆盖率从 0 到 80%

本节目标

给 AI 的指令(强调"先读后写"):

读 src/legacy/calc.js(一个无测试的计算模块),先列出它的公开函数与边界,
再为每个公开函数写单元测试,覆盖:正常值、边界值(0/负数/空)、异常输入。
用 Node 内置 test runner,最终 npm test 通过且覆盖率>=80%。

AI 产出的测试样例(节选):

// test/calc.test.js(由 AI 生成,node --test 运行)
const test = require('node:test')
const assert = require('node:assert')
const { add, divide } = require('../src/legacy/calc.js')

test('add 正常相加', () => { assert.equal(add(2, 3), 5) })
test('add 处理负数', () => { assert.equal(add(-1, 1), 0) })
test('divide 正常', () => { assert.equal(divide(6, 3), 2) })
test('divide 除零抛错', () => { assert.throws(() => divide(1, 0)) })

运行方式:npm install --save-dev(若需覆盖率工具)后 node --test;要看覆盖率可加 c8 之类工具。AI 难以一下到 100%,但 0→80% 的安全网已是质变。

为什么值:测试既是"回归安全网",也是"活文档"——后人读测试比读注释更快懂函数意图。

名词解释

课后练习

  1. 为什么给遗留代码补测试要先"列公开函数与边界"再写?
    • 答案:先理解接口与边界,测试才覆盖真实行为;否则 AI 可能基于错误假设写测试,覆盖率虚高却无保护。
  2. 覆盖率是不是越高越好?
    • 答案:不是。超过某阈值后每提升 1% 成本陡增,且 getter/纯样板代码的覆盖收益低;80% 左右常是性价比拐点。

总结

给遗留代码补测试,是 Vibe Coding 最"功德无量"的应用之一。旧系统没人敢动,根因是"没有安全网"——而 AI 恰好擅长"读懂旧代码、按接口批量生成测试"。这一步让覆盖率从 0 跳到 80%,本质是把"无人敢碰"变成"改了能立刻发现坏没坏"。我特别想强调测试的双重身份:它既是回归安全网,也是可读性最强的活文档。新人读测试,三秒就懂一个函数该干嘛、边界在哪。但也要警惕覆盖率崇拜——100% 不是目标,80% 的关键路径覆盖远比 100% 的样板覆盖有价值。用 AI 补测试的正确姿势是"先读后写、聚焦边界、跑通为准",而不是让它闭眼刷数字。