`
yunzhu
  • 浏览: 1141192 次
  • 性别: Icon_minigender_1
  • 来自: 南京
博客专栏
B2b19957-cda7-3a9e-83a0-418743feb0ca
监控应用服务器
浏览量:109119
2e8be8be-e51f-346c-bcdd-12623c9aa820
Web前端开发
浏览量:119263
Bfa5df64-a623-34b9-85b8-ef3ce2aed758
经典异常的解决
浏览量:204006
社区版块
存档分类
最新评论

对单元测试的一点感悟

阅读更多

想当年毕业设计就是测试驱动开发,所以从刚入行开始就对单元测试、测试驱动开发有比较深入的认识,刚开始一直作为敏捷开发的忠实粉丝。但是几年工作下来,我开始对单元测试持矛盾的态度:单元测试当然是一种很好的创举,但是具体使用当中,它却经常会产生种种负作用,使开发人员望而生畏。这当然不是因为单元测试这一技术或思想本身的问题,而是实践这一思想的人的问题。

 

当前很多公司使用单元测试的怪现象:
如今,很多公司为了说出去好看——我们的开发遵循敏捷开发,拥有近100%的单元测试覆盖率,所以代码质量有非常可靠的保障。但是实际上,单元测试都是软件已经开发完成之后加上去的,而且经常还是由专门分配的几个人去写单元测试的,而这几个人根本不熟悉需求,甚至根本没有参与开发过程,或者参与得很少,而分配给他们写单元测试代码的工期当然也相当紧,毕竟,这也是需要成本的啊。所以,最终导致的结果就是——为了达到高覆盖率的目标,为每个方法(不管有无必要)加上单元测试,简单看一下这个方法,然后从对这个方法的肤浅理解出发,即开始动手,写一个或很少的几个测试用例,这样单元测试覆盖率100%的要求很快就达到了,可是这样的单元测试有用吗?答案不言自明。

 

这种怪现象一般可能具备哪些特征呢?

1、整个开发过程完全之后写单元测试——这是单元测试的时机问题

2、由非开发过程的参与者写单元测试——这是单元测试的执行者的角色问题

3、由不了解需求的人员写单元测试——这也是单元测试的执行者的角色问题

 

那么,这种行为会带来哪些负作用呢?

1、这浪费了时间和人力成本

2、这会带来负面的情绪影响

这些人是带着抵触的厌烦的情绪投入工作的,因为明知这样的工作是无用功,仅仅是面子工程,却不得已而为之,自然没有兴趣没有热情,而这一情绪会横向和纵向地散发,从而给团队带来负面的影响。

3、这些单元测试代码毫无用处,甚至产生负作用

对于后来者来说,这种单元测试代码没有任何作用,因为写作者本就是在不了解需求的基础上仓促写就的,那么自然对后来者理解需求没有任何益处;而且如果后来者相信的这份单元测试代码,没有充分地调查具体的实现代码,还会因此产生误解。

 

单元测试到底要怎么写?何时写?

这是一个很值得探究的问题,但是有十足的必要。

在酷壳上看到“单元测试要做多细”这篇文章,文章是从StackOverflow上的一个问题开始引入的。

 

这个问题是:

TDD需要花时间写测试,而我们一般多少会写一些代码,而第一个测试是测试我的构造函数有没有把这个类的变量都设置对了,这会不会太过分了?那么,我们写单元测试的这个单元的粒度到底是什么样的?并且,是不是我们的测试测试得多了点?

 

问题的最佳答案是:

老板为我的代码付报酬,而不是测试,所以,我对此的价值观是——测试越少越好,少到你对你的代码质量达到了某种自信(我觉得这种的自信标准应该要高于业内的标准,当然,这种自信也可能是种自大)。如果我的编码生涯中不会犯这种典型的错误(如:在构造函数中设了个错误的值),那我就不会测试它。我倾向于去对那些有意义的错误做测试,所以,我对一些比较复杂的条件逻辑会异常地小心。当在一个团队中,我会非常小心的测试那些会让团队容易出错的代码。

 

看了这个最佳答案,给人感觉对单元测试持一定的否定态度和不感冒态度。但是知道这一最佳答案的回答者是谁吗?是Kent Beck。对,正是那位极限编程、测试驱动开发和单元测试以及JUnit的创造者Kent Beck。Kent Beck的答案,正好回答了单元测试该怎么写、要写到什么程度、何时应该写这几个问题。

 

我的一些观点:

对于如何进行单元测试,有这么几个观点:

一、单元测试的时机很重要

无非两种:

一是在具体实现代码之前,这就是所谓的测试驱动开发;

二是与具体实现代码同步进行,正是大部分人采用的方式。

那种事后单元测试,基本是没用的。当然有一种例外:要对没有单元测试的既有代码进行维护和改造,这时候需要为既有代码追加单元测试,但是这也得建立在充分调查理解需求的基础上才能进行。

二、单元测试的执行者的角色

单元测试应当由具体实现代码的开发者进行,也就是说每个开发人员都应当同时对自己负责具体实现代码和单元测试代码负责。

这里也存在同第一条中的例外的情况。

三、单元测试应当突出重点

应当对那些重点部分重点关照,主要有:

1、逻辑复杂的

2、容易出错的

3、不易理解的,即使是自己过段时间也会遗忘的,看不懂自己的代码,单元测试代码有助于理解代码的功能和需求

4、后期需求变更可能性相对比较大的,这样后期需求更变修改代码之后就不用太担心写的代码对不对以及是否破坏既存代码逻辑了

四、单元测试也应注重质量,不要写无用的测试代码

写没有实际用处的单元测试不如不写,正如注释,写没有意义的注释也不如不写,既降低代码可读性又容易误人子弟。

五、敏捷开发的宗旨是“以人为本”,是解放,而不是压迫

单元测试虽说从长期来看,可以提高代码质量、减少维护成本、降低重构难度,拥有众多好处。但是从短期来看,肯定是会加大工作量的,也就是说需要投入更多的人力成本,如果只想得到好处,却不愿投入相应的成本,还是不要搞单元测试了——那只会导致开发人员更多的加班,不会产生好的效果。因为整个敏捷开发的宗旨,是“以人为本”,而不是从开发人员身上榨出更多的油水。单元测试是为了解放开发人员,而不是压迫,是为了从长远的角度减轻开发人员的工作量!

 

最后要说的是:

那种为了单元测试而单元测试的愚蠢行为应当立即停止。

那种只是想把单元测试作为一项面子工程的行为更应当停止(官场的种种坏习惯不应该在思想纯洁的程序员当中流行)。

那些对单元测试没有深入理解,只是希望今后能冠以“单元测试覆盖率100%”荣誉头衔的团队,应该立即停止这种想法。

单元测试不应当过于重视覆盖率,而应该在需要的时候写单元测试。何时写,怎么写,都需要建立在开发者已经对单元测试有深刻理解的基础上。

单元测试也是一把双刃剑,要用得好它才能发光发热,产生强大的正能量,请不要把它当作“龙泉宝剑”挂在自家的玄关辟邪。

10
0
分享到:
评论
10 楼 yunzhu 2013-05-07  
kanme818 写道
现实点的说,国内80%的项目都压的很紧,普通开发就加班到死了,哪里还有力气单元测试.只要测试没测出BUG,就过去了,相信不是开发的人故意要这么干,实在是因为累啊。

是啊,很多时候,那是被逼得没有办法。
虽说单元测试从长期来看,可以提高代码质量,减少维护成本,降低重构难度。
但是从短期来看,肯定是加大工作量的,对于那些常年进度紧张加班如家常便饭的开发人员,确实会成为很大的负担,领导总是既想得到回报,又不想耗费更多的成本,那怎么能行呢。
9 楼 yunzhu 2013-05-07  
mike.liu 写道
文章写得不错。但是让开发人员自己决定写单元测试代码,经常是下面两种情况:
1. 那些会主动写单元测试代码的,通常水平都很高,也许写单元测试必要性紧迫性不是那么强,只需要在关键的地方又单元测试就可以了;
2. 那些水平差的开发人员,只会把单元测试当做任务来完成,不会或没能力思考哪些地方需要有单元测试,哪些地方又没必要。

说得有道理,所以单元测试也应该纳入一定的软件流程管理,需要一定的规范化以及质量监督
8 楼 yunzhu 2013-05-07  
white_crucifix 写道
请教一下,我不太理解“同步”进行是什么意思。我一般是写完一系列函数,用简单一个测试类测过以后,再加上单元测试。

看看这篇文章,我比较赞同文中的观点:
何时编写单元测试?
http://www.blogjava.net/jiangshachina/archive/2008/06/09/206812.html
7 楼 weng 2013-05-07  
mike.liu 写道
文章写得不错。但是让开发人员自己决定写单元测试代码,经常是下面两种情况:
1. 那些会主动写单元测试代码的,通常水平都很高,也许写单元测试必要性紧迫性不是那么强,只需要在关键的地方又单元测试就可以了;
2. 那些水平差的开发人员,只会把单元测试当做任务来完成,不会或没能力思考哪些地方需要有单元测试,哪些地方又没必要。

你看到了问题所在
6 楼 weng 2013-05-07  
很有探讨意义的文章
5 楼 kanme818 2013-05-06  
现实点的说,国内80%的项目都压的很紧,普通开发就加班到死了,哪里还有力气单元测试.只要测试没测出BUG,就过去了,相信不是开发的人故意要这么干,实在是因为累啊。
4 楼 mike.liu 2013-05-06  
文章写得不错。但是让开发人员自己决定写单元测试代码,经常是下面两种情况:
1. 那些会主动写单元测试代码的,通常水平都很高,也许写单元测试必要性紧迫性不是那么强,只需要在关键的地方又单元测试就可以了;
2. 那些水平差的开发人员,只会把单元测试当做任务来完成,不会或没能力思考哪些地方需要有单元测试,哪些地方又没必要。
3 楼 white_crucifix 2013-05-06  
请教一下,我不太理解“同步”进行是什么意思。我一般是写完一系列函数,用简单一个测试类测过以后,再加上单元测试。
2 楼 yunzhu 2013-05-05  
finallygo 写道
而实际上,我看到更多的公司是一点单元测试都没有.... 其实能重视测试已经很不错了,有单元测试至少能让开发人员在设计的时候会考虑解耦合,还有可测试性,这从一定程度上来说,是提高了代码的质量,至于测试的质量问题又是另外一回事了,所以,我觉得有还是比没有好

这里涉及到一个问题,那就是单元测试的时机。
如果单元测试是由具体实现代码的开发者写的,而且是开发过程当中“同步”进行的,那么这个单元测试就可以达到很好的效果了。就像你说的,可以促进开发人员写出耦合度低、职责单一、设计合理的代码,因为代码写得很搓的话是很难写单元测试代码的。所以说,敏捷开发,其实核心就是人,是通过促进人向更好的方向发展,而达到好的效果。
1 楼 finallygo 2013-05-05  
而实际上,我看到更多的公司是一点单元测试都没有.... 其实能重视测试已经很不错了,有单元测试至少能让开发人员在设计的时候会考虑解耦合,还有可测试性,这从一定程度上来说,是提高了代码的质量,至于测试的质量问题又是另外一回事了,所以,我觉得有还是比没有好

相关推荐

Global site tag (gtag.js) - Google Analytics