先写个失败测试,AI完成迭代少37% —— Cursor TDD实战

你听说过“测试先行”能让AI编程也提速吗?Cursor Labs的内部研究给出了一组硬核数字:先写一条会失败的测试用例,再让AI根据它生成代码,整个功能的迭代次数平均减少 37%。这个结论不是实验室里拍脑袋算的,而是跟踪了真实开发者的 prompt 链得到的。

为什么会有这种效果?因为当你把一条红测试(Red Test)递给AI时,你等于画了一个非常清晰的“靶子”。AI知道了接口签名、边界条件、断言形状——所有实现细节都已经被测试“规定”好了。没有这个约束,AI很容易跑偏,写出一堆抽象但用不上的代码,然后你不得不再用三、四个 prompt 把它改回来。测试就像一份“已编译的规格说明书”,AI照着它生成,几乎不会跑题。

举个例子,上周我需要实现一个 checkRateLimit 函数,放在 middleware/rateLimit.ts 里。我写了一条 feature.spec.ts,里面包含三个用例:

// 测试1:突发请求是否被正确限制
test('burst allowance should block after exceeding limit', () => {
  // 模拟10个并发请求,预期第11个返回429
  const result = checkRateLimit({ userId: 'test', burst: 10 });
  expect(result.allowed).toBe(false);
  expect(result.status).toBe(429);
});

// 测试2:窗口重置后应恢复可用
test('window reset should allow requests again', () => {
  // 假设窗口过了5秒,预期重新允许
  const result = checkRateLimit({ userId: 'test', windowMs: 5000 });
  expect(result.allowed).toBe(true);
});

// 测试3:响应头应包含剩余的速率信息
test('response headers should include rate limit metadata', () => {
  const result = checkRateLimit({ userId: 'test', burst: 10 });
  expect(result.headers['X-RateLimit-Remaining']).toBeDefined();
});

这几个测试全部是红(失败)的——因为函数还没写。然后我把 feature.spec.ts 扔给 Cursor(在同一个 prompt 里),它一次就生成了正确的实现,所有测试瞬间变绿。而就在几周前,我用一段“自然语言描述”让它写同样的功能,反复改了5轮才搞定,每次都是边界条件算错或者 header 逻辑漏掉。

差别在哪?就是那套“测试脚手架”。你的测试就是给 AI 的“战场地图”,它不需要猜测你要什么,直接按照地图上的点把它填满就行。

所以,如果你正在用 Cursor 做开发,下次开工时先新建一个 feature.spec.ts,在里面写一条肯定会失败的断言(一条就够了,越多越清晰)。然后把这个文件作为 prompt 的唯一上下文,让 AI 照着实现。记住这个口诀:测试第一,prompt 第二。37% 的迭代就是这么省下来的。

类似文章