很长时间没有自己写博客了,前两个月看了一些关于测试驱动开发(Test-Driven Development, 简称TDD)和敏捷软件开发(Agile Software Development)是否有用、是否一定得用的争论,很精彩,也很引人思考。尤其感谢酷壳网的站长陈皓先生将这些观点搜罗起来并发表了自己的看法。

  在我的同事(尤其是小利)面前,我一直装着是个敏捷的忠实粉丝,但是严格的来讲,任何一种开发方法学都不能强制地推广到所有开发者的身上。一个磨合良好的团队应该以人为出发点,而不是以规则。不同风格的开发者在一系列松散的规则下互相磨合的工作,才是健康的一个开发循环。

  我很难相信,有很多没有做过项目甚至不曾钻研技术的人去做敏捷谘询师。尽管一直很想做技术谘询业,但是一直对这个敏捷培训行业没有太多深入的了解。有朋友如果对敏捷谘询这种行业有自己的见解,那么我是急于认识的。

  敏捷软件开发那个话题太大,尤其是非技术面的观点融入进来之后,容易变成清谈,所以今天先不提。着重说一下对测试驱动开发的看法。TDD存在的主要问题就是,如果需求不是很明确,或者需求提出方变动特别频繁,那么回导致测试代码频繁的变更,从而减缓甚至干扰工程进度。还有就是特定开发人员的思维与TDD的流程磨合不融洽。所以并不是一定要强制进行TDD。测试并行、测试后行都是可以被接受的。但是应当给全体团队讲授TDD思想和技术,因为其中一些特定细节,比如边界值检测,按契约编程,前条件、后条件测试,对于非TDD测试照样可用。

  相比强制推行TDD而导致的低效,另外两种做法则是更不能容忍的。一种是等代码逻辑全部完成之后,匆忙补写测试用例,并且只测试想当然的情境,得出 “果然成立”的结论后,就匆忙提交了。例如写一个ArrayList,测试了add(Object)方法前后的size大小是否差1,就认为add方法实 现正确了,根本不管add(null)或者多次add同一个引用时是否结果正确。这种态度就是事先拟定了一个“正确”的路径,然后沿着这个路径草草写就一个测试用例,不管其它路径。是一种不负责任的态度。质量管理人员或者团队成员有义务阻拦这种代码进入代码库。如果因为工期的关系必须出产品,那么官方的主干版本也绝不应该允许这种代码入库,至多只能提交到beta分支上。待原作者补完合格的测试后,再行并入主干。

  另一种则是根本不进行任何测试,等待一个集中的时间补写,例如产品3.0版本发布后抽出一周专门补写。这种规划基本是精神胜利法式的管理。自认为测试已经在精神上被“写完备了”,只是没落到代码上而已。然而在实际的工程里,根本不会有任何人再去补写这部分测试了,所有人会立刻投入下一个版本或产品的开发中去。

  比较稳妥的办法是当代码主路径及一些支流路径初具规模时即开始着手规划测试,然后通过测试来完善代码流程中的疏漏,同时根据代码流程的变化(可能是需 求变更引发的)来更新测试用例。这时代码和测试基本处于稳定状态,管理起来也比TDD风险小很多了。总之,团队成员的测试警觉度和技术管理者对测试代码质量的高要求可以淡化TDD的强制性,作出一种柔性测试的氛围。这对于团队的磨合是有益处的。

  关于如何写好测试的问题,我阅读还不是很深入,初步可以肯定有价值的资料除了Kent Beck的《测试驱动开发》,还有Gerard Meszaros的《xUnit Test Patterns : Refactoring Test Code》。后者是一本字典式的参考书,可选读。也欢迎发现有价值的JUnit等单元测试参考书的朋友及时告知。