为什么要写单元测试

大部分人写单元测试的目的是因为领导或者公司要求写单元测试,好多规定了单元测试的覆盖率,通过和CI的集成很容易统计每个项目的单元测试覆盖率。另外一些人内心觉得单测可能有所帮助的,但是又觉得高覆盖率的单测需要超过写代码的时间,觉得太浪费时间了,尤其大部分项目都是时间紧,任务重,所以他们就挑好写的随便写写,算是对自己有了交代了,因为他们觉得完全不写单测似乎有点山寨的样子,但是也没有那么重要。

当然也有好多程序员真正意识到单元测试的巨大作用,他们是发自内心的重视单测,觉得单元测试和代码一样重要。

单元测试给我们带来的好处

写单元测试是需要花费大量的时间和精力的,所以如果没有足够的好处是没人愿意写的,我个人总结的写单测能够给我们带来的几个好处:

  1. 验证我们代码的正确性,我们写完代码通常要自己测试验证一番才会交付给QA进行测试。通常大家自我测试的方法就是跑一些程序,简单测试一下其中主要的分支场景,如果通过就认为自己的代码没有问题可以交付给QA了。但是事实上运行代码是很难测试一些特殊场景或者覆盖全部分支条件,比如很难模拟IOException,数据库访问异常等场景,或者穷尽各种边界条件等。而我们通过单元测试可以很轻松的构建各种测试场景,从而几乎100%确认我们的代码是可以交付给QA的。
  2. 保证修改(重构)的正确性,很多时候我们不该修改(重构)老代码的原因,就是不知道它的影响范围,担心其它模块因为依赖它而不工作,有了单元测试之后,只要在改完代码后运行一下单测就知道改动对整个系统的影响了,从而可以让我们放心的修改(重构)代码。
  3. 可以加深我们对业务的理解,写单测得过程其实就是设计测试用例的过程,需要考虑业务的各种场景,从而可以使我们跳出代码来思考业务,这样可以反过来思考我们的代码是否满足业务的需求。
  4. 单元测试是最好的开发文档,传说中单元测试就是最佳的开发文档,因为单元测试覆盖了接口的所有使用方法,是最好的示例代码。而真正的文档包括注释很有可能和代码不同步,并且看不懂。

如果我们不写单测会怎么样

我们可以不写单测吗?当然可以,事实上很多人确实是不写单测的,尤其进度压力比较大的时候,好多时候写单测也只是为了应付公司覆盖率的要求的。但是如果你不想写单测请回答如下2个问题:

  1. 你怎么证明你的代码是没有问题的,如果不能证明那么事实上是你将有缺陷的代码交付给了QA,由QA保证质量
  2. 你们团队有足够的优秀的测试人员吗?

先写单测还是后写单测

先写代码后写单测,其实是为了保证或者验证我们的代码的正确性。先写单测后写代码也就是测试驱动开发(TDD),其实是从业务角度驱动开发,思考的方式完全不同。

先写代码后写单测,很有可能落入一个误区,那就是照着代码写单测,难道这样做不对吗?其实这样做只能保证你写出来的代码都是对的,但是并不能保证你没有漏掉一些分支条件。而测试驱动是从业务场景出发,是真正意义上的先设计测试用例,然后写代码,这样做其实通常是为了证明你的代码是错误的,这也是QA存在的目的,他们的出发点绝对不是为了证明你的代码是对的。

如果不是按照先写测试后写被测试程序的红,绿,重构方法原则,测试编写很可能会变成一种体力劳动。很多开发人员在开发完某个功能后才去写测试方法,把这当成一种在提交代码前需要完成的行政命令来执行,这样做其实意义不大。

到底多少的单测覆盖率是科学的

在问这个问题之前,首先你得问一下自己哪些代码不需要写单元测试,为什么。排除了这些真正不需要单测的代码外,你应该覆盖你的每一行代码。

然而在现实中,很多时候因为水平有限,导致写的代码很难写单元测试,比如私有方法,或者私有方法中调用私有方法,目前我们要求公开接口中的代码必须全部覆盖,私有方法没有作太多的要求。

私有方法是否需要单元测试

私有方法有很多好处,然而私有方法是很难进行单元测试的,或者说需要付出更多的代码进行测试。很多专家都推荐不要对私有方法单独进行测试,而是通过测试调用它们的公有方法进行测试。

通常私有方法不要处理过多的业务逻辑,最好只是简单的数据处理的工具方法,否则代码结构可能不合理。当发现代码不好写单元测试时,很有可能是提示你要重构你的代码了。

为什么我们没有好好写单元测试?我们写单元测试的障碍是什么?

既然单元测试有这么多的好处,我们为什么写不好写单元测试呢?

  1. 并没有真正体会到单测的好处,好多人可能听说了单测很有用,但是并没有切身的体会到单测带来的价值,另外可能潜意识中认为发现bug是QA的工作,导致内心并没有重视单测。我经常听大家说我代码已经写好了,还需要一下单测,证明大家并没有把单测和代码放在同一层次。说白了就是觉得单测没有啥用。
  2.       
  3. 领导不重视,很多时候表面上看领导非常重视单测,说单测一定要达到多少覆盖率。但是足够好的单测至少需要不少于写代码的时间,领导很多时候其实并不愿意把这部分时间估算进任务中去。所以说要想让程序员写好单测,必须给他们留出必要的时间,否则程序员一旦面临进度压力时怎么取舍是可以预料的,代码都写不完,哪有时间写单测。

参考文献