发布于 

C++杂谈003. 聊聊TDD

TDD(Test-Driven Development)是一种敏捷开发方式,主张:先写测试,再实现功能。

TDD的核心流程可以总结为:红绿重构,感兴趣的话可以去看Kent Beck的《测试驱动开发》,这里仅记录几点对TDD的思考。

  • 思考1、测试驱动开发 vs 测试先于开发

TDD真的只是“先写测试,再写开发”吗?如果只是这样的话,为啥不叫测试先于开发,或者先测试后开发?

这里的关键是如何理解“驱动”二字。个人理解,它隐含着从过程向目标的逼近。测试用例是预期的”目标“,这个目标可大可小,简单的比如解析一个字符串参数,也可能复杂到比如:求解一个图的最短路(对我来说确实挺难的)。但用例一旦写出来,就划定了目标,告诉开发者这个功能的表现是什么样的。另一方面,开发功能代码是”过程“,不断的去接近并最终达到目标,让用例通过,这就是我自己所理解的“驱动”的内涵:以终为始,先定目标,再向目标冲刺。

第2个点,TDD中的T并不是指所有种类的测试,这里专指Unit Test。UT区别于其它类型的测试的是,它的粒度很细,测试对象是函数粒度。前面说用例是“目标”,那这么小的目标意味着什么?这就需要”任务分解“。不断地把大的、不能立即实现的功能拆分成:小的、可轻易实现的细粒度功能。不断地准备好这些”水泥沙子“,高楼大厦的目标也就不远了。

  • 思考2、TDD意味着高质量的编码,不做低效重复功

使用TDD开发的代码,是具有自验证性质的代码。当代码有bug时,通过用例集,可以快速分析定界。
另外,用例集本身构筑了一道“墙”,墙内是充分验证过的区域,可以提供承诺的功能;墙外是未定义的行为或各种灾难的场景,这不是我们的软件所能处理的。有了这道墙,才可以衡量代码的好坏,才会逐渐形成高质量的编码。

  • 思考3、TDD不应该是强制约束,而应该是一种选择。

刚接触TDD时,会觉得很别扭:作为一个开发,编码为啥要从用例开始写?其实不必为了TDD而TDD,TDD固然好,但按照常规的方式——先写功能代码再写UT也没啥问题,核心在于:需要想清楚将要开发的特性表现的行为是什么?并且这种行为要能够被自动看护起来(为了不在相同的问题重复投入)。这样看,TDD只是恰好符合这一点的开发模式之一而已,它只是”术“,不是”道“,不必苛求,但确实可以作为一种不错的选择。