learn-tdd
零门槛 30 分钟学会测试驱动开发:一个自动售货机案例,带你走完 Red-Green-Refacto
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
零门槛 30 分钟学会测试驱动开发:一个自动售货机案例,带你走完 Red-Green-Refacto
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
图1:TDD 循环:Red(写失败测试)→ Green(写代码通过)→ Refactor(重构)
想象一下,你接手了一个「用胶带粘起来」的老代码库。改动一个模块,另一个模块突然报错;修了一个 Bug,隔壁功能直接崩溃。团队里没人敢动核心逻辑,因为没人知道动完之后会炸出什么。这种状态下,所谓的「敏捷迭代」不过是走钢丝。
dwyl/learn-tdd 的作者——英国软件开发团队 dwyl(全称「Do What You Love」)——正是从这种痛点出发,设计了这门课程。他们在 README 开篇放了一张「胶带粘出来的汽车」图片,毫不客气地点出:没有测试的代码,就是随时可能散架的临时凑合品。
dwyl 是一个拥有 417 个公开仓库、776 名关注者的教育型开源组织,专注于软件开发最佳实践的普及。learn-tdd 是他们最受欢迎的项目之一,目前拥有 2785 个 Stars,帮助了无数 JavaScript 开发者理解 TDD 的精髓。
TDD 的核心理念用一个公式概括:先写测试(Red),再写代码(Green),最后重构(Refactor)。
具体来说,开发流程变成了三步循环:
Red(写失败的测试):先想清楚你要实现什么功能,用测试用例把它「问」出来。测试当然会失败,因为代码还没写。
Green(让测试通过):写最少量、最朴素的代码,让刚才失败的测试通过。不追求优雅,只追求正确。
Refactor(重构):在测试保护下,放心地清理代码,消除重复、提升可读性,不用担心改坏已有的功能。
这个循环看起来「慢」,实际上通过提前暴露问题大幅降低了后期 Debug 成本。正如 F1 维修站的工作人员需要「像时钟一样精准」的流程,TDD 就是让团队进入这种精密协作状态的训练方法。
learn-tdd 的教学设计非常精妙——用自动售货机找零计算器这个具体场景,串联起 TDD 的完整流程。场景设定如下:顾客投入硬币购买商品,自动售货机需要计算出应找的零钱。商品价格和已付金额已知,需要算出找零所需的硬币组合。
整个项目可以在一个 index.html 文件里完成。引入 QUnit 测试框架和 Pure CSS 美化样式后,浏览器打开即可看到测试面板。

图2:初始状态,两个测试——一个通过(绿色),一个失败(红色),失败是故意的
图中左侧绿色 PASS 表示「1+1=2」示例测试通过,右侧红色 FAIL 是故意写错的测试,用来演示什么是「预期的失败」。
教程的第一个真实任务是:实现 getChange(1, 1) 返回空数组(当付款等于价格时无需找零)。
Red 阶段:编写测试,预期返回 [],刷新浏览器——测试失败(红色)。

图3:Red 阶段——红表示测试未通过,这是正常的起点
Green 阶段:写出最简实现 return [],刷新后测试变绿。通过后,教程引导学生继续添加新测试:getChange(215, 300) 找零 [50, 20, 10, 5]。

图4:Green 阶段——绿表示代码满足测试要求
教程专门配了一张解剖图,清晰标注了 QUnit 单元测试的三个组成部分:

图5:描述(Description)+ 运算(Computation)+ 断言(Assertion),三者缺一不可
一个测试回答三个问题:「我要验证什么行为?」→ 描述;「实际计算结果是什么?」→ 运算;「这个结果符合我的预期吗?」→ 断言。
Bonus Level 1 引入了代码覆盖率工具 Istanbul(通过 istanbul cover test.js 在命令行运行)。覆盖率报告能显示哪些代码「没有被任何测试覆盖」,从而发现「潜伏代码」——看起来测试全绿,但有未测试的分支逻辑藏着 Bug。

图6:Istanbul 覆盖率报告——绿色覆盖,红色盲区,一目了然
教程还设计了一个「坏人代码」场景:一个心怀不轨的程序员在 getChange 里埋了一个后门——当 cashPaid == 1337 时多找零 5 英镑。常规测试全部变绿,但覆盖率工具会立刻发现这段代码从未被测试覆盖,从而暴露问题。
learn-tdd 虽小,五脏俱全,展示了完整的现代前端测试工具链:
| 工具 | 作用 |
|---|---|
| QUnit | 浏览器端测试框架 |
| Istanbul | 命令行覆盖率分析 |
| JSDoc | 自动生成 API 文档 |
| GitHub Actions CI | 每次提交自动跑测试 |
| Codecov | 覆盖率趋势追踪 |
项目采用 CDN 加载依赖的方式运行,零安装门槛。所有测试库均从公共 CDN 引入,package.json 中的 devDependencies 仅用于本地覆盖率分析和文档生成。这种设计让学生真正做到「下载即用」,专注于 TDD 思想本身,而非环境配置的泥潭。
尽管 learn-tdd 是极佳的入门教程,它也有值得注意的局限:
1. 示例过于简单:自动售货机找零算法是经典但理想化的场景,实际项目中的 TDD 涉及更多复杂边界条件(异常处理、异步操作),初学者毕业后仍需大量实践。
2. 面向纯前端:项目仅覆盖浏览器端 JavaScript,对于后端 Node.js、TDD 在微服务中的应用、或者测试数据库交互等场景均未涉及。
3. 缺乏 AI 辅助测试的讨论:2025 年 AI 辅助测试已成趋势,LLM 可以根据需求描述自动生成测试用例骨架,但本教程完全聚焦手写测试,对这块新兴趋势没有涉及。
learn-tdd 目前拥有 2785 个 Stars,在 GitHub TDD 教程类项目中名列前茅。最后一次活跃更新为 2025 年 10 月,Issues 区(21 个 open)持续有新手提问。
在 AI 时代,TDD 反而更加重要:LLM 负责快速原型,测试套件负责确保生成代码符合预期行为,两者的结合才能真正提升工程效率。
零门槛路线(推荐新手):
git clone https://github.com/dwyl/learn-tdd.git 下载仓库index.html,跟随 README 步骤执行进阶路线(有 Node.js):
npm install 安装依赖(Istanbul、JSDoc)npm test 运行覆盖率测试npm run docs 生成 API 文档
图7:当所有测试变绿时,代表你已掌握 TDD 基本功
本报告基于 dwyl/learn-tdd GitHub 仓库(Stars: 2785,License: MPL-2.0)分析生成,数据截至 2025-10-13。