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

对单元测试的一点感悟

阅读更多

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

 

当前很多公司使用单元测试的怪现象:
如今,很多公司为了说出去好看——我们的开发遵循敏捷开发,拥有近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  
而实际上,我看到更多的公司是一点单元测试都没有.... 其实能重视测试已经很不错了,有单元测试至少能让开发人员在设计的时候会考虑解耦合,还有可测试性,这从一定程度上来说,是提高了代码的质量,至于测试的质量问题又是另外一回事了,所以,我觉得有还是比没有好

相关推荐

    人教版小学四年级语文下册第二单元测试题.doc

    人教版小学四年级语文下册第二单元测试题,是一个综合测试学生在多方面语文能力的工具,为学生提供了提升和检验学习成果的平台。以下,我们将深入解析这份测试题所涵盖的知识点,探究其在语文学习中的重要性和作用。...

    2020年人教部编版七年级语文上学期第二单元测试卷(含答案).pdf

    2020年,人教部编版的七年级语文上学期第二单元测试卷不仅是一份考核学生学习成果的试卷,更是对当前教育质量的一种检验。这份测试卷的问世,标志着基础教育阶段对学生语文能力培养的具体要求,其涉及的题目类型及...

    语文同步练习题考试题试卷教案七年级下册语文第二单元测试卷.pdf

    七年级下册语文第二单元测试卷是一份针对性极强的学习资料,它不仅覆盖了广泛的基础知识领域,还旨在通过多种题型的练习,考查学生的综合语文运用能力。 首先,汉字拼音的正确读音是学习语文的基石。例如,试卷中的...

    高一语文上册第四单元综合测试3[精选].doc

    这种对比揭示了不同诗人对于山水诗的不同理解和表达方式,反映了个体对自然美的不同感悟和情感表达。 此外,李贽的观点在试题中也有所体现。他提出自然之道即日常生活,这与杨万里山水诗的世俗化倾向不谋而合。李贽...

    七年级语文上册第一单元综合测试题1冀教版

    通过冀教版《七年级语文上册第一单元综合测试题1》我们可以清晰地看到这一点。该测试题是一份全面检验学生语文综合能力的试题,它不仅覆盖了基础语文知识,还包括了古诗词学习、读书活动策划、抗震救灾主题宣传等多...

    四年级语文上册第五单元课外阅读专项测试卷新人教版

    综上所述,四年级上册第五单元的课外阅读专项测试卷不仅仅是一次简单的语文知识测试,它还是一个引导孩子们深入思考、感悟生活、学会尊重与理解的过程。通过这样的学习,学生们将在语文知识掌握的同时,得到思想上的...

    九年级语文下册第一单元创新能力综合测试.pdf

    【知识点】 1. 语文基础知识:此...总的来说,这份综合测试旨在检验学生对语文基础知识的掌握,包括古诗词积累、语言运用、修辞手法、阅读理解及情感表达等方面的能力,同时也涉及到了个人价值观和生活感悟的培养。

    同步精品课堂2015_2016学年高中语文第一单元综合测试提升版新人教版必修1

    这一点在“同步精品课堂2015_2016学年高中语文第一单元综合测试提升版新人教版必修1”中得到了充分的展现和讨论。 首先,新诗的“变”与“常”是理解中国现代诗歌发展的关键。新诗的出现,标志着中国诗歌从古典形态...

    九年级下第一单元创新能力综合测试-7页.pdf

    7. **联想与感悟**:从盲人养花的故事中,可以引导学生思考个人价值实现和对他人的影响,培养积极的生活态度和人际交往意识。 虽然这些内容不属于IT专业领域,但它们代表了教育过程中的关键环节,如批判性思维、...

    三年级语文上册 期中测试卷 北师大版 试题.doc

    北师大版三年级语文上册期中测试卷正是针对这个学段学生的学习情况进行了一次全面而深入的考查,内容涵盖了语文知识的各个方面,从基础知识到写作技能,从阅读理解到语言实际应用,每一点都旨在培养和提升学生们的...

    七年级政治上册第一单元第一课第框校园风景线学案无答案教科版道德与法治.doc

    8. **达标检测**:测试题主要考察学生对新环境适应、校训理解和学校认识的掌握程度。例如,第一题强调新起点的重要性,第二题强调校训在学校文化中的地位,第三题则要求学生认识到每个学校都有其独特性。 总的来说...

    学生信息管理系统java课程设计报告含源代码.docx

    4. **系统测试**:这部分内容未给出详细信息,但通常会包括单元测试、集成测试和系统测试,以确保所有功能的正确性和稳定性。 5. **心得体会**:开发者或学生可能会分享在设计和实现系统过程中所学习到的经验和感悟...

    五年级语文教学总结.doc

    针对这一点,我在课堂上不断强调认真书写和按时完成作业的重要性。我注重观察学生的学习状态,对那些作业拖沓、书写马虎的学生给予更多的关注和指导。对于学习上存在困难的同学,我耐心辅导,鼓励他们克服学习障碍,...

    reading-notes:阅读笔记,例如书和博客等

    10. 测试和调试:单元测试、集成测试、TDD(测试驱动开发)。 通过阅读这样的笔记,不仅可以系统地学习JavaScript,还能了解到作者在学习过程中的思考和感悟,这对自己的学习路径和问题解决策略会有很大的启发。

Global site tag (gtag.js) - Google Analytics