Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

单元测试

复习

  • 契约、错误与异常:明确的前提与承诺
  • 从算法到软件:软件需要长期维护
  • 日志与调试:问题要能被定位

TL;DR

  • 单元测试针对最小的功能单元验证行为
  • 它小而快,可以反复自动运行
  • 它保护模块的行为不被后续修改破坏
  • 好的单元测试聚焦“一个行为”,输入输出清晰

正文

  软件要长期维护,就意味着代码会不断被修改。怎么保证“改这里,不会弄坏那里”?一个核心手段是单元测试(unit testing)。

测最小的单元

  单元测试的“单元”,通常指最小的可测试功能块——一个函数、一个方法。

  测试的写法很直接:准备输入,调用它,然后检查输出是否符合预期。 比如测一个“求最大值”的函数:给 [3, 1, 2],期望得到 3;给它一个空数组,期望按约定处理。

  它和上一章的“契约”正好呼应:单元测试,就是在验证这个单元有没有履行它的承诺。

小而快,还能反复跑

  单元测试有几个讨喜的特点:

  • :只测一个功能,目的明确
  • :不依赖复杂的运行环境,几毫秒就能跑完
  • 可自动化、可反复:改完代码,一键全跑一遍

  前两点让它写起来轻松,第三点才是它最大的价值。

它保护“已有功能”

  单元测试最强大的作用,其实是保护已经写好的行为:一旦某个改动破坏了原有功能,那个对应的测试就会立刻失败,把问题当场暴露出来。这就是所谓的回归保护

  于是,你在重构或加功能时,就有了底气:只要测试还是绿的,就说明原来的承诺依然成立。

  它还能当活文档:一个测试用例,等于一个“这个函数该怎么用”的清晰例子。比注释更可靠,因为它能被真正执行、被验证。

  把“我改的对不对”这件事,交给机器反复替你确认——这正是单元测试的价值。

思考题 1

  单元测试的“单元”指什么?它有什么好处?

思考题 2

  为什么单元测试能“保护”已有功能?

小结

知识点

  • 单元测试针对最小的功能单元验证行为
  • 它准备输入、检查输出,验证契约
  • 小而快、可自动化反复运行
  • 能提供回归保护,并充当活文档

参考资料

  1. Wikipedia(zh):单元测试:针对最小功能单元的测试
  2. Wikipedia(zh):回归测试:确认修改未破坏既有功能

思考题答案(仅供参考)

思考题 1

  “单元”通常指最小的可测试功能块,例如一个函数或方法。好处是目的明确、编写与运行都很轻快,可自动化反复执行,能及早发现问题,也便于验证函数是否履行契约。

思考题 2

  因为它把该单元应有的行为固化成了可反复运行的检查。一旦后续修改破坏了原有行为,对应测试就会立刻失败,从而当场暴露问题,起到“回归保护”的作用。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪