最近接手了一个项目发现单测的覆盖率非常低,所以在组内做了下单元测试的分享,顺便梳理了之前的一些实践经验,如果有错漏的地方,烦请指出。
为什么不愿意写单元测试
在日常的开发中,如果团队没有对单元测试率做出一定的要求,或者有要求但是执行不严格的话,那么项目的单测覆盖率一定是很低的,要靠自驱去编写大量的测试用例需要开发有良好的代码习惯。不愿意单测的原因也非常明显:
项目排期时间紧张
在国内的互联网环境下,项目排期时间紧是常有的事情,甚至经常是项目倒排期,这种时间的紧张的情况下,自然写单测的就很少,毕竟大家都要赶进度。 我认为短期的项目排期紧张是可以理解的,如果长期处于这种状态那么需求管理一定是有问题的。
增加代码量
毫无疑问写单测会增加代码量,甚至单测的代码量有时会超过你要测试的代码量。懒是人之常情,所以开发经常会在本地简单测试一下就提测了,不会去写单元测试。
构造测试用例很麻烦
这种情况也很常见,经常可能你想写一下单测但是发现单测需要的输入构建起来很麻烦,然后你就不想写了。
为什么需要单元测试
有那么多理由不写单元测试,那为什么我们还需要单元测试呢?
降低bug率
这应该是单元测试的主要目的了,没人能保证自己写出的代码没有bug,覆盖率高的单测能提前帮你发现这些bug并修复它,而不是等到测试给你提出或者上线后服务报警或者客户投诉。
帮助自己思考代码结构是否合理
在编写单元测试的时候,你能再思考一遍自己的代码实现是否合理,这在我看来是单元测试最重要的一点,也是帮助代码能力进步的一种方式。如果你再写单元测试的时候发现非常困难,那么你可以看看是否是自己的实现有问题。
测试用例能帮助理解代码
项目经常会有合作或者交接的时候,这种时候测试用例能帮助新人快速的了解你的代码,起到一部分文档的作用。这也是提升你代码可读性的一种方式。
怎么写单元测试
单元测试的规范可以参考《阿里巴巴Java开发手册》的单元测试章节,在此我就不赘述了。我分享一些我的实践经验。
工具
一般常用到的单测框架有Junit和Mockito,一个测试框架,一个mock框架,两者能解决绝大部分的测试需求。
单测的典型格式given-when-then三段式
given:给出测试的初始条件和状态
when: 执行要测试的代码
then: 验证结果
一个测试一个断言
不要再一个测试里放很多断言,这样容易导致测试代码语义不清晰,可读性差。尽量一个测试一个断言,一个测试一个概念。
Mock掉外部依赖
如果你测试的代码依赖外部调用,那么应该mock掉这部分调用,保证你单测的独立性,让你的单测即使是在断网的环境依然可以正常运行。
只测试公有方法
这个建议并不绝对,在大多是情况下我们应该只测试公有方法,不破坏代码的封装。一般公有方法都会调用私有方法,所以只测试公有方法也能覆盖私有方法。
参考
《代码整洁之道》
《代码大全》
最后
自己的总结难免有偏颇错漏,如果有好的建议或者意见也可以互相探讨。