zxuanzi 2010-05-27
TDD,敏捷编程中一个成功的个人实践。
重第一次接触到在工作中使用这个实践,到现在已经过去半年了,有不少的优点,以及一些个人感觉不舒服的地方。
我们先来简单的说说什么是TDD:
三条定律,以及F.I.R.S.T五个原则。下面的定义是重别处拷贝的:
这就是TDD的灵魂思想(这都归功于Tim):
#1.Bob大叔的三条定律
*没有测试之前不要写任何功能代码
*只编写恰好能够体现一个失败情况的测试代码
*只编写恰好能通过测试的功能代码
#2.FIRST原则
*Fast:测试要非常快,每秒能执行几百或几千个
*Isolated:测试应能够清楚的隔离一个失败
*Repeatable:测试应可重复运行,且每次都以同样的方式成功或失败
*Self-verifying:测试要无歧义的表达成功或失败
*Timely:频繁、小规模的修改代码
写程序代码的时候,一开始我完全的遵循三大定律。
先说说这样带来的好处,
1.所有的代码都是以测试为基础的,所有的方法都被调用到,命名也很好,毕竟是在写测试的时候调用的,很明确的知道这段代码需要实现什么功能。
2.所有的代码测试覆盖率基本超过95%,
3.代码短小,功能明确,避免了不少粘贴复制的方法,使用TDD的时候你会不自觉的主动抽取相同代码的函数,这个很奇怪。
4.更加明确我们需要实现的功能,每一个测试都是一段功能的实现,只有分析出需要的功能才会有一个测试,才会有一个失败,才会有一段修改或者新加的代码。
使用测试驱动开发的时候很多时候,我们需要认真的思考,我们是不是完全作到了所有的测试,我们所有的功能是不是都已经实现了,有没有一些基本测试没有作到。
不舒服的地方,因为每一个测试一段代码,我们的每一个测试其实要求的是一个明确的返回,所以我们可以写出欺骗的代码,呵呵:)。
例如:我们有一个向右转的代码,我们第一个测试是我们面对东方,向右转,那我们面南
我们的函数是tnRight();
publicvoidtnRight(){
return"west";
}
这段代码的测试可以跑过了,可实际上这不是我们要的代码,我们不得不再加一个测试,你面南,向右转。
这种小步的向前跑动,让我们十分的难受。
TDD让我们可以自由发挥的代码,受到了限制,我们不得不按照一个平稳的速度前进,让人十分不不爽。
还有,在我们写完测试准备优化代码时,发现代码中有个时候明显存在一个错误,需要增加一个条件(这中情况是因为测试考虑不全造成),可是我们不能直接加,我们需要编写一个失败的测试,然后修改代码,这种时候,让人心里洋洋的,不舒服。
以前我们可是分析完功能后一口气写上几个类,十多个函数,上百行代码,那种舒服爽快的感觉,没有了。
可是我还是坚持使用TDD,因为所有的代码都有测试,它保证了所有的基本功能的实现都是可靠的,更加深入的理解功能,分析功能。无论以后代码如何变化,我都知道,那些基本功能需要实现的功能都有测试可以保证,不会出现丢失。