鸟食轩

 Microsoft .NET[C#] MVP 2003
随笔 - 424, 文章 - 233, 评论 - 5417, 引用 - 344
数据加载中……

都在说TDD开发,那到底TDD是什么?

    想了半天,确实是记不得什么时候第一次听说TDD了,我这里是要拍(拍板砖的拍)这个所谓的TDD,所以也就懒得去找TDD到底是什么时候提出来的,虽然google一下可能在第一页就能有正确的命中(比如wiki百科,哦可惜不能访问了)。对TDD我还是了解一点点的,至少知道它被大家叫做Test Drive Development,不过我觉得过分强调这个东西真的有些无聊,甚至是相当的无聊。

    程序员进行开发的动力是靠Test来Drive吗?这显然是极其荒谬的结论,因为有这样一个大家还基本能赞同的观点,那就是:高质量的程序是程序员编写出来的,而不是测试出来的。所以对于程序编写,测试如果是锦上添花,那么最终结果是非常棒的。而如果测试成为了雪中送炭,那么这个产品或项目注定了就是一坨屎。程序的质量和TDD有什么关系呢?

    TDD是束缚程序员生产力的桎梏,同时TDD也是程序员推卸和逃避责任的法宝。程序员是思考型的工作者,而不是流水线上的装配工人。虽然今天在一些特定的场景里,程序员可以像标准件一样被任意的替换,但不得不说这样的程序员其实就是编码工人而已,就像拿到图纸后就知道该怎么砌砖的建筑工人一样。为什么说TDD阻碍生产力?这很明显,编写测试用例需要时间和精力呀。当然很多人会说自测试是程序员的责任,如果不编写测试用例,不做Unit Test,怎么来保证程序员的代码质量?编程是一种还算有些创造性的工作,而不是挖一个坑种一个萝卜的机械劳动。测试用例只是对矛盾的一种转换,比如我应该让我的程序处理3种输入,结果我把这个任务转换成了:我有3个测试用例,我的程序需要通过这3个测试用例。到底程序员是在干嘛?为了测试用例而编程吗?由于测试用例也是程序员自己写的,所以测试用例的错误和失误风险和程序的风险等效。实际上程序员还是在为自己编程,为自己的思考编程。这样一来到底是自己的思考犀利敏锐,还是把思考变成了测试用例更加有效?我觉得自然的思考最有效率,而用心的思考最有效果。而隔了一层测试用例的思考,使人更加容易出错和生长惰性,因为增加了步骤和莫名的依赖,觉得通过测试用例就万事大吉。殊不知自己编写的测试用例只是思考的一种转换,一种更加难以把握重点和实质的转换,因为编程的动力已经变成Test的结果了。

    关于使用TDD来重构更是骗小孩的把戏。TDD强调的就是要通过测试,别的都不再重要。任何"多余"的功能,就是Unit Test Case没有覆盖的功能,就没有了任何实现和处理的价值,编写这样的处理代码被认为莫名其妙,因为它们不会被测试,也没有这样的Unit Test Case。作为一个真正的程序员,是不会容忍初始的代码实现是一坨屎,然后再来根据什么Test Case重构成Perfect的代码的。因为第一次的思考一般是严肃的,第一次编写的代码是最有灵犀的,它不是在后来懒心无肠就能修改出来的。反而后来的代码更多的就是为了亮绿灯而已,效率和美感荡然无存。这有点像是在污蔑真正认真重构代码的人吧?其实不是,如果你真是认真地人,为什么在开始不仔细思考,把那些编写所谓Test Case的时间用来编写好你的第一版代码,然后认真地用"心"执行几次呢?因为这样的代价其实是在debug时不可避免的,如果真要完全(注意是完全)依赖绿灯,这也就是严重的开发效率问题了。

    版本升级和延续又真的能依靠TDD吗?首先我们假设升级和延续的改动是有限的,否则成了重写就不在这个讨论之列了。测试依靠测试用例,测试用例如同代码注释、开发文档,它们同样存在着过时和与实现不同步的问题,这都需要维护。而且写得ugly的Unit Test Case和滥注释滥文档是一样的,到后来根本没有用也没有任何人愿意再去维护修改趟这个浑水。真正的版本升级和延续的保障是Product Team人员的稳定。如果从设计到实现甚至测试,主要人员都很稳定地一直做下来,那么新的设计和改动实现后要不稳定都难。这是TDD能Drive的吗?一些惜墨如金的注释,一堆莫明其妙的开发文档、啰里啰唆的n多Unit Test Case,不知道新来的人面对后怎么开始他的延续工作?

    所以到底什么是TDD?什么才是有效的TDD?真正的TDD应该是:Thinking Drive Development。真是郁闷,缩写还居然一样,算了,就沾点恶名吧。程序员进行直接的缜密思考,他提交的代码才会是sexy的,他的开发效率也才会是最高的,所谓磨刀不误砍柴功正是如此。而Unit Test Case、Unit Test只是开发方法有益的补充,不是主要矛盾所在。

posted on 2006-06-24 01:47 birdshome 阅读(11510) 评论(34)  编辑 收藏 所属分类: 其它编程相关内容

评论

#1楼    回复  引用    

无论哪种XDD,都是经过合理的Think,至于采用那种X,是根据每个人每个项目的类型决则的。
TDD难道不经过Think就能开始么?
2006-06-24 04:55 | zdnet [未注册用户]

#2楼    回复  引用  查看    

楼主说的有点过火了,TDD就像一支笔,有的人只能乱涂,有的人就可以画出漂亮的画.还是看个人,这和TDD本身是好是坏无关.
至于是否只要通过测试,我觉得这点很现实,客户要的东西就测试,不要的就不测试.能过测试就OK,测试用例一般都不是由程序员写,至少不是自己写给自己用.
2006-06-24 08:43 | 极地银狐.NET      

#3楼    回复  引用  查看    

Birdshome拍的有些过了吧:-),TDD,听起来似乎有些离经叛道,却又是合情合理,测试不应该是锦上添花,也不应该是雪中送炭。
2006-06-24 09:03 | TerryLee      

#4楼    回复  引用    

真吃惊搂主的理解。

大家编写了功能后谁都会测试,如果运行不通过就是还有问题,
其实每个人都是测试驱动,因为测试反映需求,只不过一般测试(接口设计)先在脑子中,按照直觉编写程序,然后再测试。而TDD不过是把测试落实在方法的第一步。
测试不是凭空有的,是从需求结合设计的产物。说他如何限制程序员思维,我都很难想象程序员怎么有理由写出不符合需求的程序。
况且测试针对的是接口而不是实现细节。

单凭它可以验证所有单元的正确性和迅速定位出问题的地方,就有理由相信他可以锦上添花和雪中送炭。
2006-06-24 10:07 | yifeng [未注册用户]

#5楼    回复  引用  查看    

不知道Birdshome自己做程序怎样测试。
其实我们写程序的谁都希望写完的代码没有bug,那多爽啊。
可是现实情况,无论你怎样写都会或多或少的产生bug,我不信有人写代码从不出bug。既然总是有bug,写代码的人自己避免不了,那么就要靠一定的测试了来发现了。正是因为写程序的时候太容易出Bug,所以有些人把测试放在了一个非常重要的程度,出现了TDD。
我没怎么用过TDD,只是跟一个同学做了个小试验,那就是写一个很小的程序用了这种方法,还结对编程了,呵呵。
地银狐.NET 说的有道理。
2006-06-24 10:16 | yzx110      

#6楼    回复  引用    

对于一个单元测试没有写过多少的人,就推荐他用TDD来开发,确实是不负责任的做法。在实践TDD的时候,确实会遇到很多原来没有遇到的问题,就像上面文章中提到的,每当你构思好一个Perfect的Idea的时候,最想做的事,就是编写代码,酣畅淋漓的实现他。若是要先写测试,会让人憋得慌,但是这会让你冷静一下,因为没有大量UnitTest经历的话,写出的代码可测试性(testable)必然是很差的。
要先写单元测试,要做的第一件事就是考虑怎么样写出的代码是容易测试的,是容易构建测试环境的,容易写Mock对象的,等等。从另外一个角度来说——过度设计、高耦合、凌乱的代码是很难写单元测试的。如果在开始写代码前能够思考一下这些问题的话,对低耦合系统的设计还是有帮助的,所以说TDD并不是他名字含义那么简单,测试还驱动的设计,驱动着软件架构的改进。
当然TDD也不是万灵丹,在很多场合下用起来效果不好,比如在技术验证阶段,需求捕捉阶段,框架磨合阶段,对程序员、设计师也有比较高的要求,不光是技术还有耐心。我们目前也只在框架开发的时候,使用了TDD,业务部分还没有运用,我们的考虑是从业务最稳定的地方开始。
还有一句,我认为好代码是重构出来的,欢迎讨论。
2006-06-24 10:20 | windtower [未注册用户]

#7楼    回复  引用  查看    

没这样打击TDD的,你看看sqlite的代码,后面跟了多大一堆测试包?其他重要的软件也都一样,不然,谁能保证代码能够正确运行?谁敢用?

开发MIS应用就不要TDD了,反正也错不到哪里去多少(循环都没有,想错都难啊),实在错了,再给客户修正,还捞个售后服务佳的美名,哇哈哈
2006-06-24 11:30 | 丁丁      

#8楼    回复  引用  查看    

不说TTD,把软件开发者比作流水线上的工人,确实是胡说八道。要不那些巨头也不用去争取那些顶尖的程序员了。

测试代码更多应该是验证,而不是驱动。
2006-06-24 13:06 | 马维峰      

#9楼    回复  引用    

很赞同楼主的思想。
不过,略有不同的一点是:TDD在高质量的软件开发场合中,是有必要的。
假设,一群程序员为火箭开发程序,每一个细小的环境都是要保证绝对正确的。这样:质量高于资金,高于时间,高于程序员个人的喜好。
程序员当然要思考,但是程序员作为团队中的一员,作为整个项目的一员,只是一颗棋子而已。我们需要创新,但是大多数的时候,大多数的程序员,也就是流水线上的工人而已。恩,我还是先做好自己的本分吧!
2006-06-24 13:27 | 阿福_游客 [未注册用户]

#10楼    回复  引用  查看    

眼光放长一点,如果你的软件想做version 2.0的话,TDD绝对是有很大帮助的。
所谓的“先写测试代码,再写程序代码”的说法,也没有必要绝对化,通常情况下,我是先写interface,然后写testcase,然后再implement。
先写代码再写测试也不是一件错事,考虑到将来的version 2.0,你仍然是在TDD。
2006-06-24 15:45 | 小陆      

#11楼    回复  引用  查看    

在国内已经不能访问wiki了吗?!
2006-06-24 16:04 | smalldust      

#12楼    回复  引用  查看    

其实在没有提出TDD这个概念以前,大家就已经在这么做了,就是我们所说的“测试计划”,往往测试计划文档的编写要早于代码的编写,或者至少是同步的,TDD中的“测试用例”只是“测试计划文档”的另一种形式。但是一般“测试计划文档”中包含的东西会比较多,比如有用户界面的测试,压力测试,并发测试,等等,这些测试的需求现在的那些XUnit工具似乎是不能实现的,另外也不知道对于JavaScript这类的东西要怎么编写测试用例,所以当时我看完NUnit的功能说明文档心就凉了。
2006-06-24 22:58 | 蔡克伦      

#13楼    回复  引用    

wiki国内可以用这个wiki专门代理来访问:
145.97.39.140:80
2006-06-25 10:46 | mifly [未注册用户]

#14楼    回复  引用  查看    

唉... 望文生义啊.TDD首先是一种设计方法,然后是一种开发方式的思路,最后才是一种测试方法. 楼主还是先好好了解下比较好
2006-06-26 18:00 | woodhead      

#15楼    回复  引用  查看    

@丁丁
haha,我就是写Mis程序的,我们的服务不错的哟:)
2006-06-26 23:04 | 大剑师      

#16楼    回复  引用  查看    

OMG,lz对TDD的了解还真不是一般地浅——应该说是一点都不了解,只知道TDD是“测试驱动的开发”,是什么样的测试,怎样驱动开发完全不知道。
2006-06-27 15:31 | NetCobra      

#17楼    回复  引用  查看    

Test Driven Development
2006-06-28 12:30 | Ronin      

#18楼    回复  引用  查看    

简直就是乱弹~~~~~
2006-06-28 17:48 | №.零零伍      

#19楼    回复  引用    

可以看一下Kent Beck的那本书,挺薄的,估计一天就能看完。
2006-06-29 17:49 | robaggio [未注册用户]

#20楼    回复  引用    

我完全赞同BirdsHome。这种黑盒测试就是对车间工人的要求(对不起,我这么说似乎不尊重车间工人,但我的意思只是说工作方式不同,不是高低贵贱的意思)。有些程序员是车间工人的工作方式,有些是思考型的工作方式,一个愿意花更多的时间编写测试,一个愿意花更多的时间思考他的代码逻辑,当这两种人在一起讨论问题的时候,说不到一块去,特别是在工人占多数的情况下。对于工人来说,当你的程序通过了所有测试用例的时候,也许可以暂时满足一下那点虚荣心;对于另一种人来说,内在的完美才是让人安心和高兴的。
2006-07-03 09:48 | modico [未注册用户]

#21楼    回复  引用    

基本上我比较支持楼主的观点,在软件诞生的整个过程中测试工作一定要有,但应该重神不重形,现在好多是重形不重神,很痛苦
2006-07-13 14:01 | ayaya [未注册用户]

#22楼    回复  引用  查看    

任何方法学都有其产生的背景和适用的范围,我觉得LZ先搞清楚了TDD产生的背景和适用的范围再来考虑这个问题。可以看出来LZ对软件开发的想法仍然停留在个人英雄主义的时代,的确对某些产品和项目的开发个人就可以基本搞定,但对大多数项目和产品而言,个人英雄主义注定要失败。我觉得等LZ你成为一个大项目的项目经理时,才会真正理解什么才是真正影响项目成功与否的因素。
2006-08-07 18:28 | Koven      

#23楼    回复  引用  查看    

birdshome前辈,重庆.NET俱乐部刚成立了,把你加进去了,以后兄弟们还要多向你学习,请多多关照。
2006-08-09 22:52 | xmlsvg      

#24楼    回复  引用    

好像楼主说得有点问题:TDD 就好比小学时候做算术题的验算,因此是有用的。
2006-09-05 14:12 | Robbie Mosaic [未注册用户]

#25楼    回复  引用    

你到底自己用JUnit或者CPPUnit写没写过一个实际的项目?

我只知道我的项目组用了CPPUnit以后三个月,千行代码错误率下降到原来的1/3,进度虽然没提前,刚刚好按时完成,但是那段时间居然能做到了每个程序员都不加班。最重要的是,半年后需要重构,在核心程序员跳槽的情况下,修改并没有引入太多的BUG。

对于我们这种生物信息领域的软件来说,几乎每周都有蛋白质的新规律被加入算法,每个月世界大的仪器公司都有新产品发布(比如就在我写这个回复的时候,收到邮件,又有一种激光辅助离子源的四级杆飞行时间质铺仪发布了),传统的方式根本无法保证软件开发的质量和进度。

国内在人类基因组计划里很出色地完成了1%的基因序列,现在承担人类蛋白质组计划工作,工作量是基因的上千倍,每天产生的数据就有上T等着鉴定软件和算法,每个月都有新论文新方法(比如这周正在开发往样品里加同位素O18标记一种罕见的蛋白质的分析算法),我的经验是,只有TDD开发的生产效率才有可能满足时间和质量要求.
2006-09-08 22:18 | swxj [未注册用户]

#26楼    回复  引用  查看    

TDD的确不是适合每一个人,每一个项目和每一个团队。而且如果不是真正理解TDD的思想和实践的话,追求形式,赶时髦只会南辕北辙,事倍功半而已。
2006-09-14 09:52 | CrazyCoder      

#27楼    回复  引用  查看    

Test-Driven Development,楼主确实拍过了。要拍一个概念首先你要用用才可以说好或者不好。我怀疑LZ根本就没有应用过TDD!我虽然没有在整个项目中应用过TDD,但是在一些components上使用过。也隐约体会出好处。
TDD是一种开发方式,也是一种Thinking的方式。而不是说TDD了就不用思考了,真的这样倒是软件开发的极大极大的进步啦!TDD只是让你的开发变得更简单,代码更优雅,而不是让你先写一堆屎,再用这堆屎构建摩天大楼。TDD强调快速反复的迭代,通过强的和频繁的负反馈保证代码质量。通俗一点说,如果你不清楚自己要怎么做的时候,先想想要做什么会有很大帮助。
如果你不使用TDD,回想一下,你公开的API里面有多少根本没有人使用过?TDD告诉你不要过于笼统的考虑问题,这对我来说是最大的收获。
2007-03-17 11:41 | 肖鹏      

#28楼    回复  引用    

个人认为给自己的先上保险(TDD),是一个好方法。
楼主的理解也不是过激,只是偏了。
2007-04-18 13:55 | Given_xing [未注册用户]

#29楼    回复  引用    

光靠Think就可以做出完美的程序?我不信,不是不相信lz,是不相信我们大家。大部分人都没有这个实力。TDD适合80%的人,而且也不像lz说的那么不堪。记得写豪杰解霸的梁都说程序是调试出来的,所以把测试看得很重也没有错。
2007-07-18 12:15 | xtyyumi301 [未注册用户]

#30楼    回复  引用    

如果你真的是在全新开发一个自己想要的东西,而又没有任何现成的代码可以套用的时候,你就会知道单元测试的重要性了。
2007-09-29 16:13 | ThinMichael [未注册用户]

#31楼    回复  引用    

“序员进行开发的动力是靠Test来Drive吗?这显然是极其荒谬的结论”

站在程序员角度会如此回答。但是站在PM的角度,则正相反。
2008-04-11 15:13 | sp1234 [未注册用户]

#32楼    回复  引用    

TDD未必是桎梏开发的枷锁,但是对于绝大多数的程序员而言,没有TDD的帮助,在修改设计结构、修补漏洞上花费的时间,绝对是远大于持续重构、持续集成的时间的(而持续的重构和集成被证实是能够大大缩短集成、变动的时间的)
2008-08-13 17:41 | Andy Wang [未注册用户]

#33楼    回复  引用    

楼主典型的小屁孩愤青一个
2008-08-13 17:45 | 凉粉小刀 [未注册用户]

#34楼    回复  引用  查看    

呵呵,引起的争议不少啊
2008-10-09 22:39 | canbeing      

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-06-24 20:41 编辑过


相关链接:

历史上的今天:
2005-06-24 只遍历出JScript对象的expando属性