测试驱动开发,一直以来都是很热门的讨论,但是在国内互联网行业中,大部分的项目还是拒绝使用TDD。我自己尝试了下TDD这种开发模式,感受到为什么大家虽然觉得他很好,但使用的人很少的部分原因了。
TDD
测试驱动开发(英语:Test-driven development,缩写为TDD)是一种软件开发过程中的应用方法,由极限编程中倡导,以其倡导先写测试程序,然后编码实现其功能得名。测试驱动开发始于20世纪90年代。测试驱动开发的目的是取得快速反馈并使用“illustrate the main line”方法来构建程序。
测试驱动开发是戴两顶帽子思考的开发方式:先戴上实现功能的帽子,在测试的辅助下,快速实现其功能;再戴上重构的帽子,在测试的保护下,通过去除冗余的代码,提高代码质量。测试驱动着整个开发过程:首先,驱动代码的设计和功能的实现;其后,驱动代码的再设计和重构。
正面评价
- 可以有效的避免过度设计带来的浪费。但是也有人强调在开发前需要有完整的设计再实施可以有效的避免重构带来的浪费。
- 可以让开发者在开发中拥有更全面的视角。
负面评价
- 开发者可能只完成满足了测试的代码,而忽略了对实际需求的实现。有实践者认为用结对编程的方式可以有效的避免这个问题。
- 会放慢开发实际代码的速度,特别对于要求开发速度的原型开发造成不利。这里需要考虑开发速度需要包含功能和品质两个方面,单纯的代码速度可能不能完全代表开发速度。
- 对于GUI,资料库和Web应用而言。构造单元测试比较困难,如果强行构造单元测试,反而给维护带来额外的工作量。有开发者认为这个是由于设计方法,而不是开发方法造成的困难。
- 使得开发更为关注用例和测试案例,而不是设计本身。目前,对于这个观点有较多的争议。
- 测试驱动开发会导致单元测试的覆盖度不够,比如可能缺乏边界测试。在实际的操作中,和非测试驱动开发一样,当代码完成以后还是需要补充单元测试,提高测试的覆盖度。
以上是维基百科上面的解释。
从我个人的使用上来看,测试驱动开发虽然说是一种敏捷开发的终极形态,但是从某些角度上来看,更像是瀑布型和敏捷的一种妥协。更像是每个小迭代都是严格的瀑布型。
在瀑布型里,需求是确定的,在确定的需求下,开发和测试可以并行进行,从而保证最终的质量。在敏捷里面,需求是变更的,很多时候需要根据市场反馈进行调整,甚至在同一个开发周期内都可能发生变更,当敏捷里面使用测试驱动开发的时候,必定会浪费更多的时间在写测试上面,并且在需求变更的时候,不仅仅代码需要修改,测试代码也同时需要修改,这也有点违背了这个模式的初衷了。
现在大部分需要敏捷开发的都是业务型的产品,从我的了解,很多著名产品,都是没有白盒测试的,特别是客户端,主要进行黑盒测试。从这里面可以看出来,对测试的投入想必是非常庞大的,一般来说,测试和开发应该需要1:1的比例,但是在当前的互联网环境下,拥有如此庞大复杂的体系肯定不是一个能够快速反应的团队,也就不具备了在互联网行业的竞争优势。
在我的了解,大家叫好不叫卖的原因主要有如下几个:
- 本身白盒测试就是一个非常耗时耗资源的东西,很多情况下不可能投入如此多的资源在这上面。
- 黑盒测试已经能够满足90%的需求了,投入产出比不好看
- 产品是业务型的,对质量的要求并没有那么的高
- 缺陷的影响或者修复成本低
当然,我们要讨论的不是测试驱动开发的优劣,而是应该考虑如何利用他的优点,同时又避免他的缺点。
- 核心部分,重要部分,可以尝试使用测试驱动开发,特别是可能会用很长时间的,同时也方便未来可能的重构。
- 对于业务以及一些变动大的内容,尽量避免使用,以免未来代码改了,测试代码没有变
- 为了保证质量,除了更详细的黑盒测试以外,需要加入很多其他的措施,比如用户的反馈,奔溃异常日志的收集与统计,对于客户端产品,可能需要动态修复,来确保质量
在我自己的感觉上来说,写测试的时候的确会想到很多开发时候可能没有注意到的问题,但是在开发的时候也会感到测试没有覆盖到一些情况,这可能也是因为两种思维不停的切换吧,所以最好还是完全分开来做,不要写一块做一块。