论坛首页 综合技术论坛

中小项目敏捷实践之五(关于单元测试)

浏览 3935 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2014-05-14   最后修改:2014-06-01
**开发方法是一个系统工程,需要所有项目活动的相互配合。**

本心得是基于近两年两个中小项目(一个2000 Manday, 一个1500 Manday)的实践总结,希望能与大家一起探讨和进步。

- 自动化的单元测试是持续集成的基础
- 根据项目的实际情况,可选择不同的详细程度,例如
  • 只测试Good Scenario的输入和输出
  • 测试“精”“简”Flow的输入和输出
  • 测试每一个Service方法 (开发和维护这些测试案例将是一项很有挑战的工作)

- 自动化的单元测试的最大挑战在于已有用例的维护和理解(便于消费)《实例化需求如何交付正确的软件》 P15
- 关注长期回报
- 尽管强烈推荐单元测试,但不做单元测试,小型项目也可以将质量做得很好

单元测试

在作者程序猿从业10年的程序生涯中,这是作者程序猿本人最感兴趣,也是还没有做到的部分。包括几百Manday的小项目,上万Manday的大项目,几百人合作的大产品,无一让人满意。

但作者程序猿觉得这部分应该是可以做到的,下面做详细的分析。

下面是一些比较典型的困难,我们逐条分析。

Q1,有时间去写单元测试,不如把时间省下来开发新功能

可以想象,有这样想法的程序猿们面对了多大的压力。每天被客户和老板追着跑,不得片刻的喘息时间。可是换个角度想一想,这样的客户也很惨呢,没错,客户也会很惨,在他的追赶下,程序猿们“准时”做出了他要的功能。可是,他抱着这样的系统能睡得安稳吗?他难道就不担心半夜被他的老板叫醒臭骂一顿吗?因为系统“又”出问题了。这时候就是程序猿和客户一起偿还技术债务的时候了。

引用
技术债务最早是由Ward Cunningham提出的,当时是为了向非技术背景的项目干系人解释为什么要去做我们现在称之为“重构”的事情。Steve McConnell对技术债务的解释是:技术债务是短期的一种权宜,但从长期看相同的工作会比当前会费的成本要高很多。Jean-Louis Letouzey对技术债务的解释是:对不适合做法的补救成本的总和。


那为什么不写单元测试就是一个技术债务呢?作者程序猿想用采访的方式来分析这个问题。

作者程序猿:如果不写单元测试,如何去保证质量呢?
程序猿:手工测试也可以达到同样的效果。
作者程序猿:OK,同意。

作者程序猿:假设完成一个完整的功能(功能A)总共需要10天,在第一天你需要测试你当天写的代码吗?
程序猿:当然。

作者程序猿:在第五天,你会测试你第一天写的代码吗?
程序猿:也许。

作者程序猿:在第十天,你会测试你第一天写的代码吗?
程序猿:应该会做一个回归测试的。

作者程序猿:在第十天,你会详细测试你第一天写的代码吗?
程序猿:应该会的。
作者程序猿:你真是一个好程序猿,赞!

作者程序猿:一年后,如果你改动了功能B的代码,但“有可能”会影响到功能A,你会去测试功能A吗?
程序猿:当然要去测一下。

作者程序猿:会完全测试功能A吗?
程序猿:是的。
作者程序猿:你真是程序猿界的楷模,再赞!

作者程序猿:测试时,改代码花的时候多,还是测试的时候多呢?
程序猿:测试的时间比修改代码的时候多多了。

作者程序猿:两年后,这个大项目的开发团队解散了,由你负责项目的维护。这时候,如果你改动了功能C,但可能会影响功能D,要命的是功能D并不是你开发的,你会怎么办?
程序猿:我会做Impact Analysis,做Regression Test,做详细的测试。

问题问到这里,这位可爱可敬的程序猿会有两种发展方向。要么成为圣斗士,要么成为烈士。你觉得哪种可能性更大一点?

这时候维护这个项目所花的成本将会非常高昂。这就是开发时所再来的技术债务。

如果项目的目标是“完成”,而不是“高质量”,甚至用户自己都不关心质量时,什么TDD,什么CMM都是噱头,吃饭喝酒才是方法论的核心。

注:单元测试不是导致难以维护的唯一原因,但是,是非常重要的一个原因。

这里介绍一下质量铁三角,就是范围、时间和成本,三者中任意一方的变动都会对其它二者产生影响。项目管理的目标是平衡三者的关系,使之达到最佳的效果。所以,如果希望提升质量,在时间和成本都不变的情况,只有控制范围,从作者程序猿个人的经验来看,这是对项目影响最小的方法。至于控制的方法已经在需求篇(http://www.iteye.com/topic/1134230)中详细描述了,这里就不再累赘。

Q2,需求变了不停,代码跟着改了不停,维护那些单元测试不是更浪费时间

对于这个问题,我们还是使用采访的方式来分析。

作者程序猿:如果需求变了不停,你是如何保证质量的呢?
程序猿:我会将修改的地方做详细的测试。

作者程序猿:那么那些没有被改动,但可能被影响的地方呢?
程序猿:我也会详细的回归测试。

作者程序猿:测试时,改代码花的时候多,还是测试的时候多呢?
程序猿:测试的时间比修改代码的时候多多多多了。

作者程序猿:会不会有什么遗漏呢?是如何保证的呢?
程序猿:。。。。。。

对于一个复杂的系统,如果没有很好的测试案例做支撑,将会有很多的时候花费在分析和测试上,而开发时间所占的比例也会越来越少。


(此图是从Design Debit的文章中借鉴过来的)

Q3,如果好好写单元测试,测试的代码比系统的代码还多,真的承受不了这样的成本

对于这个问题,从实用主义的角度来说,作者程序猿认为应该采用二八定律,使用20%的时候测试80%的Case就可以了。当然,这要视具体的系统而定。一丁点的错误对于航天飞机来说就是100%的失败。但对于作者程序猿现在所从事的大型银行项目来说还是适用的,因为它有一定的机制去弥补或控制某一个系统的错误不会造成银行的损失。

引用
二八定律也叫巴莱多定律,是19世纪末20世纪初意大利经济学家巴莱多发明的。他认为,在任何一组东西中,最重要的只占其中一小部分,约20%,其余80%的尽管是多数,却是次要的,因此又称二八法则。


回答这个问题,作者程序猿认为,根据项目的实际情况,可选择不同的详细程度,例如
  • 只测试Good Scenario的输入和输出。这是在项目时间非常有限的情况下,又不想完全放弃质量保证的退而求其次的选择,因为这个选择花费的时间非常有限,但却保证了系统的最基本功能的正常运行。相当于冒烟测试,可用性测试。
  • 测试“精”“简”Flow的输入和输出。这就是二八定律中的二,能够测试系统的主要功能,又不至于引入过多的测试案例而导致系统的成本压力和案例维护的复杂性。如果做到这一点,保证程序猿们安稳睡觉应该不成问题。所以,这应当是大多数项目的追求目标。
  • 测试每一个Service方法 (开发和维护这些测试案例将是一项很有挑战的工作)。这个规则相对简单,但实作起来非常难以做到。难不是因为测试案例非常多,而是如何维护和管理这些案例。


Q4,那些简单的代码真的要测吗?比如CRUD操作

相对于上面的问题,作者程序猿觉得这是一个非常现实的问题。也是一个仁者见仁智者见智的问题。或者,换个角度看,这根本就不是个问题。问题在于我们决定选择哪种详细程度的测试。

结语

没有单元测试,持续集成将是纸上谈兵,没有自动化的单元测试,每天去Build一下系统干什么呢,只是为了看看代码能不能编译通过吗?

没有测试就没有勇气和信心,只有恐惧和焦虑。Phlip说,写测试要一直写到恐惧转变为厌倦为止。

没有单元测试,就如同盲人走盲道,指不定哪个“好心”的程序猿早就给你铺好了一条“康庄大道”等着你。



所以,如果客户或老板要求广大程序猿们写写单元测试,实在不是什么过分的要求,他们也只不过想睡个安稳觉,大家都不容易,就圆了他们的梦吧。

值得思考的问题

在敏捷团队里,测试团队如何继续发挥作用?显然,大量的手工测试已经不能满足快速交付的需求。

推荐三本书

  • TDD《测试驱动开发》(美)Kent Beck著,白云鹏译,机械工业出版社
  • BDD《实例化需求 团队如何交付正确的软件》[塞尔维亚]Gojko Adzic著,人民邮电出版社
  • ATDD《验收测试驱动开发》[德]Markus Gartner著,人民邮电出版社


如何准备测试数据

如果有哪位程序猿朋友正在为准备单元测试的测试数据烦恼,希望下面的绿色小工具能帮到你。

数据驱动测试(三) – 使用工具 http://www.iteye.com/topic/1133877

  • 大小: 32.9 KB
  • 大小: 47.4 KB
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics