一、TDD入门:什么是TDD、TDD的三大原则(红-绿-重构)、TDD与传统开发模式对比、TDD的优势与挑战

好,咱们直接进入正题。

TDD,全称 Test-Driven Development,中文叫测试驱动开发。说白了,就是先写测试,再写代码。这个顺序,跟大多数人习惯的“先写代码,再测试”正好反过来。

我第一次接触TDD时,心里也犯嘀咕:代码都没写,测什么呢?这不是本末倒置吗?后来真正用起来才发现,嗯,这玩意儿确实有点东西。

1.1 什么是TDD?

TDD不是一种测试技术,而是一种设计技术。它的核心思想是:通过测试来驱动代码的设计和实现。

具体流程是这样的:

  1. 先写一个会失败的测试(红)
  2. 写刚好能让测试通过的代码(绿)
  3. 重构代码,让它变得更好(重构)

循环往复,直到功能完成。

核心要点:TDD关注的是“代码应该做什么”,而不是“代码怎么实现”。

我个人的习惯是,拿到一个需求后,先不急着写代码。我会先问自己:这个功能最终要输出什么?边界情况有哪些?异常怎么处理?想清楚这些,再开始写测试。

1.2 TDD的三大原则:红-绿-重构

这三个词,是TDD的灵魂。咱们一个一个说。

原则一:红(Red)

先写一个会失败的测试。为什么?因为你要证明你的测试是有效的。如果一个测试一开始就通过了,那它可能什么都没测到。

举个例子,假设我们要写一个加法函数:

// 第一步:写测试
const { add } = require('./calculator');

test('adds 1 + 2 to equal 3', () => {
  expect(add(1, 2)).toBe(3);
});

这时候运行测试,肯定会报错——因为 add 函数还不存在。这就是“红”。

小技巧:红阶段不要写太多测试。一次只写一个,聚焦在最小的功能点上。

原则二:绿(Green)

写刚好能让测试通过的代码。注意,是“刚好”,不是“完美”。

// 第二步:写实现
function add(a, b) {
  return a + b;
}

module.exports = { add };

运行测试,通过。这就是“绿”。

我曾经见过有人在这个阶段就开始优化代码,加各种边界判断。其实没必要。先让测试通过,后面有的是时间重构。

原则三:重构(Refactor)

测试通过了,代码能跑了。但代码写得怎么样?有没有重复?有没有可以优化的地方?这时候就可以放心大胆地重构了。

为什么?因为你有测试兜底。改错了,测试会告诉你。

// 第三步:重构(假设后续需要支持更多功能)
function add(...args) {
  return args.reduce((sum, current) => sum + current, 0);
}

重构完,再跑一遍测试。绿,说明没问题。

注意:重构阶段不要新增功能。只改结构,不改行为。新增功能请回到“红”阶段。

1.3 TDD与传统开发模式对比

咱们来做个对比,看看TDD和传统模式到底差在哪。

对比维度 传统开发模式 TDD模式
开发顺序 先写代码,后写测试 先写测试,后写代码
测试覆盖率 容易遗漏,补测试像交作业 天然高覆盖率,每个功能都有测试
代码设计 容易过度设计或设计不足 测试驱动设计,刚好够用
调试时间 后期集中调试,耗时巨大 边写边测,问题早发现
重构信心 不敢改,怕改出问题 有测试兜底,放心改
文档价值 测试用例常被忽略 测试即文档,可读性强

你看,差别还是挺明显的。传统模式像是“先盖楼再验收”,TDD则是“边设计边验收”。哪个更靠谱?你想想看。

1.4 TDD的优势与挑战

任何方法论都有两面性。TDD也不是银弹。

优势

  • 代码质量高:每个功能都有测试覆盖,bug率明显下降。我在一个项目中实践TDD后,线上bug减少了大概60%。
  • 设计更清晰:写测试倒逼你思考接口设计。如果测试很难写,说明你的代码设计有问题。
  • 重构更安全:这个前面说过了,有测试兜底,改代码不心虚。
  • 文档即代码:测试用例就是最好的使用文档。新同事看测试,比看文档快多了。

挑战

  • 学习曲线陡:刚开始会很不习惯。我刚开始用TDD时,前两周效率反而下降了。这是正常的,熬过去就好。
  • 初期速度慢:写测试确实需要时间。但你要算总账——后期调试时间省下来了。
  • 不适合所有场景:UI界面、复杂集成测试,TDD用起来会比较吃力。这时候可以结合其他测试策略。
  • 团队共识:如果团队只有你一个人用TDD,效果会大打折扣。需要大家一起配合。

我的建议:不要一开始就追求100% TDD。先从核心业务逻辑开始,慢慢扩大范围。我曾经在一个项目中,只对核心模块用了TDD,效果已经非常好了。

好了,第一章就到这里。记住三个关键词:红、绿、重构。这是TDD的基石,后面的所有内容都建立在这三个原则之上。

下一章,咱们会实际搭建一个Node.js项目,开始写第一个TDD测试。准备好了吗?