为啥需要单元测试

单元测试即对程序模块进行正确性检验的测试工作。

单元测试是程序员基本的技能之一,很多刚入门的程序员对单元测试存在以下误解:

  • 单元测试不是测试人员的事情么?
  • 自己为什么要测试自己的代码?
  • 单元测试的成本这么高对于产品开发有意义么?
  • 我这么牛我不需要单元测试!

好,现在来讲讲为啥非要单元测试呢?有什么具体的好处呢?
首长需要澄清的一点是,编写单元测试不但不会浪费你的时间,反而很大程度上能避免你因为突发 bug 而加班的情况。联想到在学校生活里,每学完一个单元,也会有一个单元测试,过了这个测试再学下一个单元,心里是踏实的。如果前面的工作没做好,就接后续的工作,到时候遇到问题又要折回来查看自己前面出了什么遗漏,那就很耗费时间精力了。

所以单元测试有两个基本的好处:

  • 确定什么正常工作
  • 检测什么停止了工作

能俗地说,就是检测这个单元中你会了哪些东西,还没掌握哪些东西,对自己的学习情况有一个清楚的认知。

那么,什么是优秀的单元测试呢?有以下几点内容:

  • 应该覆盖各个流程,异常条件
  • 单元测试的运行速度要快
  • 可重复执行
  • 单元测试之间不能有相互依赖,应该是独立的

总结一下,也就是说单元测试要“小而专注”。
什么是“小”,即每次只测试一个独立的功能点,如果你的测试点比较大,那么测试的内容之间可能是有相互联系的,你并不能明确地清楚到底是哪里出了问题。
那什么是“专注”呢,就是说在编写测试时,心里应时刻明确每个测试是用来检测什么错误的。一个bug应该是对应一个测试失败而不是多个,并且测试的命名要明确测试错误产生的原因。

下面简单介绍一下几个常用的后端测试框架:
Jest
facebook 坐庄
基于 Jasmine 至今已经做了大量修改添加了很多特性
开箱即用配置少,API简单
支持断言和仿真
支持快照测试
在隔离环境下测试
互动模式选择要测试的模块
优雅的测试覆盖率报告,基于Istanbul
较新,社区不十分成熟
全局环境,比如 describe 不需要引入直接用
较多用于 React 项目(但广泛支持各种项目)

Mocha
灵活(不包括断言和仿真,自己选对应工具)流行的选择:chai,sinon
社区成熟用的人多,测试各种东西社区都有示例
需要较多配置
可以使用快照测试,但依然需要额外配置

Tape
体积最小,只提供最关键的东西
对比其他框架,只提供最底层的 API

Jasmine
开箱即用(支持断言和仿真)
全局环境
比较’老’,坑基本都有人踩过了

总结一下,Mocha 用的人最多,社区最成熟,灵活,可配置性强易拓展,Jest 开箱即用,里边啥都有提供全面的方案,Tape 最精简,提供最基础的东西最底层的API。

下面简单地介绍一个Mocha的使用方法:
为啥需要单元测试
为啥需要单元测试

为啥需要单元测试

为啥需要单元测试

为啥需要单元测试

为啥需要单元测试
简单讲完了Mocha的使用方法,下面给大家讲一个张大胖的故事,来自刘欣所著的《码农翻身》一书。

张大胖所有的公司正在掀起一声轰轰烈烈的敏捷运动。
公司要求,每个开发人员必须掌握单元测试这个非常基本的敏捷实践。
公司要求,单元测试的代码覆盖率要达到70%。
张大胖摩拳擦掌,准备大干一场。可是刚开始就遇到了一些困惑:

  • 看看代码,action调用service, service调用dao, dao里都是sql,简单的增删查改,有什么可测试的?
  • 一些有一定业务逻辑的模块,有重度依赖关系,依赖十几个其它模块的接口,为了单独测试它们,需要做十多个mock?

一天下来,这个mock就把张大胖弄得晕头转向。
第二天便发一了状况,同组的小李修改了业务代码,却忘记修改单元测试代码,导致很多单元测试失败。小李去修改单元测试代码,可是怎么都读不懂张大胖的测试用例。
这样下去,别说业务代码了,光是单元测试维护就得把人累死。

所以,各位想想,这是为什么呢?
如果单元测试需要很复杂的setup才能开始,那就是业务代码接口有问题!
也就是说,单元测试不仅仅简单地验证了一个单元,一个功能点能不能通过,另一个作用是从侧面反映了代码结构的合理性。
所以,如果你在写测试用例的时候遇到了刘大胖类似的问题,那就需要好好反思一下整个业务代码的整体布局,有必要的话需要考虑如何重构的问题了。
参考链接:
https://zhuanlan.zhihu.com/p/25370153
https://www.jianshu.com/p/368d580d4365
https://blog.****.net/wudinaniya/article/details/81130079