上回说到,小艾明白了单元测试的重要性之后,也明白了单元测试需要测什么, 这让他的开发效率明显有了提高,而bug密度有了明显下降。但是,小艾的代码依然保持着高耦合的风格,因此编写单元测试的时候遇到了不少的阻碍,导致了测试覆盖率偏低,但是他却发现组长的测试覆盖率居然能逼近100%。
最让小艾讶异的是,产品负责人带来的用户反馈要求将已有代码进行较大幅度的变更,这个情况他简直没办法相信。就在这时,小艾听到组长说不用担心,TDD能够应付这种情况。TDD? 小艾对这个隐约有印象,似乎曾经听组长提起过,但自己对此一无所知,于是,他又来到了组长面前。
组长看到小艾对此十分感兴趣,于是也细心地讲了起来……
什么是测试驱动开发,测试驱动的工作流程
测试驱动开发每次针对一个很小的功能点,通常是小到一个单独的方法。流程:
在实现新功能之前,先考虑代码的使用需求(包括功能、过程、接口等),为其编写测试代码。
让新写的测试代码和已有的测试代码一起运行。
为新功能编写最少的实现代码,切记,是最少的实现代码。
再次让新测试代码和已有代码一起运行,根据运行结果调整实现代码,直到全部测试代码通过。
在此过程中,积极地对代码进行重构,优化代码。
重复上述操作,直到完成全部功能的开发。
概念
测试驱动开发是一种编写软件的模式,是一种敏捷开发实践。其指导思想就是让开发人员在编写功能代码之前,根据需求编写测试代码。思考如何对将要实现的功能进行验证,并完成单元测试脚本的编写,然后编写足够,仅仅是足够的功能代码满足这些测试用例,直至测试通过。
递增地在迭代中增加新功能的单元测试和功能代码编写,直到完成全部功能的开发。
目的
测试驱动开发已经不再是单纯的测试行为,而是上升到了一种设计行为,或者说,测试驱动开发的目的不是为了验证代码实现,而是为了描述一段代码的用途和用法的设计规格说明。且这种描述是无二义的,是可执行验证的。
测试驱动开发与先开发后测试的异同
相同点:
都对底层功能进行验证
都得到了单元测试资产
使项目容忍变化,可通过单元测试来保证引入的变化不会带来负面影响。
不同点:
测试覆盖率不同:测试驱动开发要求考虑全部可能的测试,几乎可达100%覆盖率。后者则相对较低。
代码可测性不同:测试驱动开发中的代码天生具有可测性,后者则不能保证。
对需求的明晰程度不同:测试驱动开发编写测试代码的过程就是从代码级别对需求逐渐明晰的过程。
测试驱动开发好处多
从上述的异同点中就可以看到,测试驱动开发所倡导的可测试的代码、单元测试覆盖、重构和更优化的设计之间,是互为因果、良性循环的行为。测试优先使得代码天生具有可测性,因此保证了近乎100%的测试覆盖率,因而bug密度较低,有利于更早发现bug。
而最大的好处在于它对代码的重构,重构可以消除重复设计,优化设计结构,使接口更简单,产生高内聚,低耦合的代码,代码复杂度的降低,也让其更便于维护。这也意味着能够最终从设计层面对代码做出改进。
测试驱动开发是敏捷开发的基础,而测试优先的方式,也能够让代码更好地适应多变的需求。
听完组长一席话,小艾明白了测试驱动开发的好处,但是很好奇,既然这么好用为什么好像没有被广泛使用呢?因为测试驱动开发相对传统开发来说,是一种观念的改变,需要时间让大家慢慢来接受。
尾声
小艾回想起在开发组的这段时间,从第一次做不正规的单元测试,到后面的测试驱动开发,既增长了自己的见识,又长了自己的本事。
第四章的内容到这里也要告一段落了,小艾协助开发人员的日子也走到了末期,应该回到自己的测试岗位去了,对代码有一定了解的小艾,相信在接下来的测试工作中,会更加得心应手~
想要第一时间看到这一系列文章的更新及更多精彩内容可以扫描下面二维码关注微信公众号: 倚楼听风雨的如月