首页 > 技术读物, 流程方法, 程序设计 > Bob大叔和Jim Coplien对TDD的论战

Bob大叔和Jim Coplien对TDD的论战

2011年6月27日 发表评论 阅读评论 9,729 人阅读    

今年春节时,我写了一篇《TDD并不是看上去的那么美》,在这篇文章中我列举了一些关于使用TDD的一些难点和对TDD的质疑,后来出现了一些争论(可参见那篇文章的评论),以及Todd同学的《TDD到底美不美》,还有infoQ中文上的那个几乎没有营养离线讨论。今天,有网友给我推来一个英文版infoQ的视频——“Coplien and Martin Debate TDD, CDD and Professionalism”,这是2008年2月18日的视频,视频的主角两个人争论TDD好还是不好,一个是敏捷社区的教主级的人物——Robert Martin(大家称之为“Bob大叔”),另一个是C++,OO,多范式编程的大师Jim Coplien(大家都叫他Cope)。这两个人对TDD的见解有分歧。Coplien的很多观点和我之前的不谋而合,而他自己称他是坚决强烈地站在TDD的对立面上。下面是Jim的原话:

I have adopted a very strong position against what particularly the XP community is calling test driven development.

InfoQ的视频很多时候相当的不给力,就像有前列腺的患者撒尿一样,半天都挤不出一滴。不过,好在那里有这两个人对话的摘录。在这里,我给大家摘要一下:

——————————————————正文分割线————————————————————

Coplien首先让Uncle Bob定义了一下TDD,Uncle Bob说明了他的三个法则:(敏捷的同学一定不陌生)

  1. 一个测试驱动的程序员,其不会在写出一个测试失败的Unit Test前,去写一句可用在生产线上的代码。(没有测试之前不要写任何功能代码)
  2. 在编写用于生产线上代码之前,不写过多的测试失败的Unit Test。(只编写刚好能体现一个失败情况的测试代码)
  3. 在现有代码通过Unit Test前,不写更多的用于生产线上的代码。(只编写恰好能通过测试的功能代码)

Coplien说他有意见的不是这三个法则,而是因为这个三个法则是孤立说出来的。Coplien说他和一些咨询师或是Scrum Master参与过很多的项目,他们发现这些项目都有两个问题:

  1. 他们使用TDD的时候,软件没有一个架构或是framework。当然,Kent Beck说——TDD可以驱使你去做架构。但是,TDD和Unit Test 是一回事吗?Unit Test是一个伟大的事,尤其是当你去写API和类库的时候。今天XP所说的TDD和UT很不一样。如果你使用TDD来驱动你的软件系统架构,那么,基本上来说,三个迭代以后,你开发的软件就会crash掉,而且无法再往前开发。 因为什么?因为连软件团队自己都受不了这三个迭代出来的架构,而且你还会发现,你根本没去去重构。
  2. 第二个问题是,TDD这种方法破坏了GUI(图形界面),就算是Kent也说:“你永远不可以在一个漂亮的界面后面隐藏一个糟糕的架构”,Coplien强烈地相信软件的架构是通过界面来发出其光芒。他觉得如果没有一个好的软件架构,这个会影响用户的操作。

Coplien接着说,如果我们使用Uncle Bob的三条法则,我们也许没有什么问题,但Coplien想告诉大家另一个非常重要的事,那就是软件架构。并说:“我根本不接受TDD是软件专业化实践的论点”

Bob大叔说,让我们回到99年,那时的敏捷社区觉得软件架构是无关的,不需要软件架构,只需要做一堆tests,做一堆stories,以及足够快的迭代,这样就可以让那些代码魔幻式地拼装起来,这就是horse shit。对于大多数的敏捷拥护者来说,这的确是愚蠢的。今天你再和Knet说这个事,他也会说那不过是一种说法。

Coplien回应到,实际上,Knet在解释XP的时候,在他的书131页的位置说过,“是的,你得做些前期的架构,但也别把自己搞乱了”。

Bob大叔把话题转回来,继续聊关于架构方面的事,他说软件的架构很重要,他也写很一些关于架构的书,他说他也是一个架构方面的怪才,但是他认为架构自己并不会形成软件的所有的外表。他觉得好的软件架构和设计能力应该出现在若干次迭代之后。他觉得你在架构软件的时候,你会创造一些东西,也会破坏一些东西,并且会在几次迭代中做一些试验性的工作,来尝试一下不同的架构。在2到3次迭代以后,你可以知道那一种架构是对的,这样,你可以在后面的迭代中进行调整 。因此,他认为架构是需要进化和发展的,而不会因为被可执行的代码所形成,也不会因为你所写的测试而形成

Coplien赞同架构进化的观点,而且他相信软件的架构的演变和进化不是因为你写的代码,也不是因为Use Case,也不是告诉你你的软件需求的范围和其中的关系,但是如果你做的方法是以增量式的,以用户驱动式的,而你却在和用户沟通时没有一些前期的业务知识,那么这一定是相当有风险的,并且你一定会把事搞砸的。

Coplien接着说,他在Knet早期提到TDD的时候和Knet时,提到YAGNI(陈皓注:You Aren’t Gonna Need It,XP的一个法则,也就是只做最简单的事)时,Kent说到:“让我们来做一个银行帐户,一个储蓄帐户”,储蓄帐户其实就是对余额进行一些加加减减的事,就像一个计算器一样。Copilen继续解释到,但是如果你要做一个真正的银行系统,你的软件架构根本不可能从一个储蓄帐户的对象(计算器)重构出来。因为储蓄帐户根本就不是一个对象,其是一个流程,后面有一个数据库的查帐索引事务,还有存款保证多和利息,还有一些转帐功能。就算是这样,这也只是用户的功能,你还需要支持税务人员和精算会计师等这些人,这会让银行系统成为一个错综复杂的软件架构,这绝对不是你可以用迭代干出来的事。当然,Bob大叔是可以的,因为他有40年的银行系统的经验。但是Bob大叔你的这40年可真不敏捷啊

Coplien接着说, 因为Bob大叔可以在软件前期做很多很重要的决定,这让得后面的事变得相对比较简单。Coplien根本不相信只要你把代码往那一放,在上面披上一层皮,再设置好一些角色,设置好接口,在文档里写上整个业务结构,而你只有在有人花钱的时候你才会在其中填充进真正的代码,反之就违反了你的YAGNI原则。所以,你只是在你需要的时候做你要做的事,但你却还是要提前得到你的软件架构,否则你一定会把你自己逼进死角的。

Bob大叔辩解到,我说的可能和你说的这个有点不同。我们应该不会像你所说的往接口中写一些抽象成员函数,而是创建一些有抽象接口的对象。当然,我不会把一下子为这个对象装载上一堆方法。那些是我需要使用测试驱动或是需求驱动来做的事,我还会随时随地在看是否哪里软件架构可以让我拆分接口。

Coplien说,问题 是你得知道你要干什么?他说他非常同意Knet的书”XP Explained”里说的——“你不能去猜”,然后他举了一个例子,一个他曾经在一个电信项目中重新架构软件的例子,这是一个长途交换机的项目,项目组特别喜欢用面向对象,有一个人需要去做一个“Recovery Object”(应该是系统恢复对象),Coplien说这是很扯的一件事,因为系统恢复根本就不是一个对象,因为他对业务不熟,所以想这么做。而当你在细节上分析的时候,你会发现这根本就不是一个有成员方法的对象。我个人认为,Coplien想用这个例子来说Bob大叔的先定义对象的抽象接口并不是一个好的需求分析的方法。Coplien还说,这个事情今天被资本化成了SOA,真是在玩火啊。

Bob大叔说,这个他很同意。你的确需要知道这个对象的意义是什么。而且他和Coplien都同意应该根据可运行的代码来决定未来,而不是基于投机心理搞一个巨大无比的架构。

此时,Bob大叔把话题又带回原地,他问Coplien:“你需要多少的时间才能写出可运行的代码?是不是一个系统需要写200万行代码才能算?”,Coplien说,在他的经历中,200万行代码算是小项目了,他的项目都是几亿行代码的。而在让代码可以跑起来,他至少需要让所有的对象都联系起来。

Bob追问到,“那么你是怎么测试这些对象的连接性的?”,Coplien说,我当然要测试,我会测试系统启动和停止,看看有没有内存问题,半小时就好了。Bob大叔似乎找到了突破点,于是说到:“Excellent!那么我们间的分歧是什么呢?也许你只是不同意TDD的概念和其专业化,当然,这是另外一个话题了”。

然后,Coplien说了一段我非常非常认同的话——“我看到很多人正在做正确的事,来避免我们之前讨论的那些问题,当然那不是TDD的扩展,而是Dan North所说的BDD。可见,软件开发中很多人在开发软件中都是在用正确的很好的方法,而我对此有意见的是,有人把这个事说成TDD,然后人们就去买相关的书来了解TDD,并且看到“architecture only comes from tests”,我在过去6个月中听到过4次这样的说法,这就像你所说的,完全就是horse shit。而关于你所说的专业化的事,如果你没有见过一个专业化你怎么知道?”。(不是吗?大多数人都知道怎么开发软件,而不是TDD才是专业化的软件开发。)

然后,Bob想多谈谈专业化的事,Bob说,在今天,一个不负责任的程序会提交一段他没有跑过单元测试的代码,所以,要确定你没有把一条没有测试过的代码提交到代码库里的最佳做法就是TDD。

Coplien完全不同意这个说法。他觉得底层的东西是更重要的。他用了一个示例来攻击Bob大叔的这个观点,他先是说代码走查和结对编程都有好的有价值的地方,当然和这个话题不相关。然后他又说了Unit Test,想想我们的单元测试,可能我们的测试案例并不可能测试我们程序中参数的各种状态,这些状态有可能只是半打,有可能是一百个,有可能是2的32次方个,所以,我们可以命中一些状态,也会没有测试到一些状态,我们的测试真的只是试验性的,所以,如果你在测试中发现bug,你真的很幸运。

随后,Coplien推崇了一个叫“Design By Contract” – 契约式设计的方法(我在软件设计中那些方法中提到过,),这个方法认为软件有前验条件,后验条件,还有不变的。这个方法是Eiffel项目使用的一个方法,使用这个方法你可以静态的去做一些检查,相当于你做了一个基础架构来干这些事。Coplien相信这个方法有TDD所有的优点——我需要努力思考我的代码,我需要思考软件的外部接口,而且,Coplien发现这么做会比做测试更有效。这会让你对那些参数的范围考虑地更为宽广,而不是只在测试案例写几个随机分散的值来测试。

今天,Bertrand Meyer(Eiffel语言的创造者,他也不赞同TDD)把这个方法推进了一步,叫CDD - Contract Driven Development,这个是一种关注于对象间关系,其在程序运行前提条件和运行后的后验条中达成一种契约,可以通过对契约条件的动态或静态的检查,来对程序的功能进行验证。这样可以让你更有效地测试程序。这种方法需要对业务的重点部位非常好的了解。这是TDD很难做到的(这就是我在《TDD并不是看上去的那么美》一文中说的TDD的测试范围是个很大的问题)。

Bob大叔似乎在努力回忆CDD和Eiffel,然后他说,TDD不就是干这个的吗?TDD就是把契约变成单元测试,不但测试输入,也测试返回值,这不就是先验条件和后验条件,而且他说,Unit Test和代码结合得更紧,而契约没有和代码结合得紧密,这是他觉得很不舒服的地方。

Coplien说Bob大叔创建了不应该创建的二元论。他说代码在哪里,UT就跟到哪里,代码有多臃肿,UT就有多臃肿,而UT也是代码,也会有BUG,所以,其实这真是事半功倍。还有一个最有名的示例是ADA编译器,其使用了TDD,反而增加了代码中的BUG,因为你的代码多,测试就多,代码就更多,整个代码就太过臃肿。如果你测试中使用了断言,这意味着你就耦合上了代码,你的测试案例和你的代码耦合地越多,你的代码就越难维护。这就是我在《TDD并不是看上去的那么美》一文中说的TDD的代码臃肿和维护问题)

Bob大叔为Coplien对代码臃肿的说法感到惊讶。Coplien说,这就是他的经历,他看到的。Bob大叔承认有很多混乱的测试和混乱的代码,他觉得像XUnit这样的工具被滥用了。Coplien打断道,这不是要和你争论的,我争论的是这就是我看到大家在实践的东西。

Bob大叔反回到,你有没有看到CDD也被滥用的情况?Coplien说,他只觉得目前,软件业对CDD用的还不够。

最后,时间不够了,Bob大叔问了一个不相干的问题,他说,我们这里有BDD,CDD, TDD, 关于DD,他不知道谁是最先第一个使用带DD这个词的,他说他好像记得一个RDD - Responsibility Driven Development。

Coplien对这个问题可能很无语,他只能说——“DD,这是Unix的一个命令嘛,Disk Dump,但这可能算。谢谢你Bob,很高兴又一次见到你 ”

——————————————————正文分割线————————————————————

看完后,我的感觉如下:

  • 这是2008年就在讨论的事,而在2011年我发布了《TDD并不是看上去的那么美》后中国这边才开始讨论。(InfoQ和 Thoughtworks怎么不去找Coplien?)
  • 英语很重要,不懂英语,只看国内的东西,你就容易被洗脑,你就需要更多的时间和精力去思考那些早被人思考过的问题。
  • 开发和测试,都是需要充分地了解业务,充分的思考,充分权衡后才能做得好的事。并不是你用了哪个方法后就专业了,就NB了。
  • 相当BS——上不谈业务,下不谈技术,只谈方法论的人和公司,这是绝对的扭曲。

(全文完)

(转载本站文章请注明作者和出处 酷 壳 – CoolShell.cn ,请勿用于任何商业用途)

——=== 访问 酷壳404页面 寻找遗失儿童。 ===——
好烂啊有点差凑合看看还不错很精彩 (4 人打了分,平均分: 5.00 )
Loading ... Loading ...
  1. sixfooter
    2011年6月27日08:59 | #1

    说得好。

    方法论只是方法论, 不能代替对业务的调研和思考。

  2. 2011年6月27日09:21 | #2

    @因为他有40年的银行系统的经验。但是Bob大叔你的这40年可真不敏捷啊
    架构已经在大牛心中, 所以他们说不用架构, horse shit

  3. 2011年6月27日09:23 | #3

    “英语很重要,不懂英语,只看国内的东西,你就需要更多的时候去思考那些早被人思考过的问题。”
    深有感触。

  4. 2011年6月27日10:15 | #4

    dd 哈,还有 DDD 呢

  5. ghostwish
    2011年6月27日11:00 | #5

    在我看来TDD根本就是一厢情愿,其存在能有意义的前提是写代码的人的水平本身够。如果你功夫水平到了一定的层次,就条条大路通罗马了,XDD都行。敏捷其实也是如此,水平不够的人尝试敏捷,出来的只能是烂东西。但是敏捷在培养一种思维和操作方式,所以你尝试敏捷自身的某些方面能够得到提升,但是TDD到不了这个层次,把他说成银弹简直就是瞎扯,或者说是horse shit。

  6. 2011年6月27日11:03 | #6

    @ghostwish
    这里说的不是银弹,而是专业化。也就是只有用了TDD或是XP才算是专业化的软件开发。

  7. Mic
    2011年6月27日11:33 | #7

    方法论当然也是重要的, 博主越来越偏激,只看到自己的正确性。

  8. Mic
    2011年6月27日11:36 | #8

    人家强调方法论,又没有说要抛开技术与业务,人家的专业本来就在方法论上, 各个科学领域那么多的纯理论研究难道在博主眼里都是shit? 博主一味批别人的狭隘,却不知道自己可能深陷在了自以为独醒的满足感里了。

  9. Mic
    2011年6月27日12:06 | #9

    @ghostwish

    无论什么方法都有一定的适用条件, TDD也是。不要总是一副看透本质的智者形象,去BS其他东西, 搞一些名词战争,本身就是一种狭隘。

  10. sjinny
    2011年6月27日12:25 | #10

    如果存在一个共识:“XDD有其自身的优点和缺点”,那么争论XDD“好坏”的意义仅在于给那些不能自己根据实际情况思考问题的人提供教条而已。

  11. jaimin
    2011年6月27日12:39 | #11

    我的实践经验是,在写测试用例的时候其实就在做架构和契约设计,写代码的时候是在实现这个架构。架构在bob大叔心中,所以他可以不用“刻意”架构,而其他的同学需要。。

  12. sjinny
    2011年6月27日12:49 | #12

    我的感觉是:UT是架构或者说设计的外观,而对应的代码实现则是架构/设计的内部构造。

  13. Hans
    2011年6月27日12:59 | #13

    @Mic
    关于你说的名词战争,恐怕敏捷社区用过更多吧。正如楼主和Jim所说,敏捷社区和TDD问题就是以为自己才是专业化的代表。关于极端,我只看到更极端吧,楼主说的是不谈技术和业务而只谈方法论,而你觉得楼主极端地不喜欢方法论,你是不是极端了?——看来过度迷信某些东西,才是极端的根源。

  14. 哈哈哈哈
    2011年6月27日13:06 | #14

    无编码不原型,无原型不设计,无设计不测试,无测试不编码。恩,就这样绕在一起了。

  15. poet
    2011年6月27日13:54 | #15

    @Mic
    其实博主不是为了强调自己的满足感,是为了针对那些专门搞方法论的咨询公司来泄私愤。把他们批倒批臭再踏上一万只脚。

  16. kaattz
    2011年6月27日14:18 | #16

    @poet
    博主那段话是强调自己的满足感,泄私愤?开始人参公鸡了吗

  17. Mic
    2011年6月27日14:46 | #17

    举个简单但是可能不恰当的例子仅供启发思维。

    大家都背过9*9乘法表,他是解决快速计算乘法的好方法。即使你根本不知道乘法究竟是什么,也能很快解决乘法问题,当然可能复杂一点就不会了。于是有个公司鼓吹并兜售这种方法给不会乘法的人。于是有些深知乘法本质,并头脑聪明的大师就看不起9*9乘法表,甚至长期地,不遗余力地揭露它的丑陋。而这个地球上很多人,依然不去学习复杂的数理本质,用背诵的9*9乘解决大部分的日常乘法问题,且觉得不错.所以那个公司也就继续鼓吹与兜售。

  18. Nogard
    2011年6月27日14:59 | #18

    @Mic @poet

    关于TDD和传统的开发方法之间的冲突,我觉得这个话题有点像是进化论/自由主义与决定论/理性主义之间的争吵。
    只是这两论争吵的焦点,这次不是在世界和社会,而是在软件这个东西之上。
    固然你可以站队为自己的信仰作选择,可是这无助于解决实际的问题。
    所以那些,认为发现了谁谁怎样说,原来目的是怎样怎样,这样的说法可以闭嘴了——你信仰什么是你的自由,但你要攻击别人怎么想信什么,那就是过分了。

    一个好的软件是怎么出来的,固然是设计出来的,但也绝对是一步一步迭代出来的。
    所谓的软件设计,我觉得实际上是一种前瞻视野,预料到某个时期内软件要应对的变化并为此提前作准备。
    如果使用TDD的过程中,只强调UT并忽略前瞻性的设计,那肯定就会如博主提到的那样,走进死角最后crash掉。

    当然,事实上很多人不会这么做软件的。

    所以你们坐而论道,不拿出实际的case出来,都是horse shit。
    而且即使一个case证明了谁的观点是对的,也无法说明TDD或者什么的就是对的。
    因为下一个case很可能就不像刚讨论完的一个。

    所以你们吵什么呢?这种事情就让成败论英雄吧。

  19. cxu2003
    2011年6月27日15:19 | #19

    个人认为,在设计的时候,必须考虑你的架构,你的函数,你的对象的可测试性。

    不一定要以测试来驱动你的开发,但如果一开始设计的时候不考虑测试这个问题,后果很严重。

    如果你在设计时考虑了这个问题,会让你的设计更好。

  20. cxu2003
    2011年6月27日15:22 | #20

    “一个好的软件是怎么出来的,固然是设计出来的,但也绝对是一步一步迭代出来的。
    所谓的软件设计,我觉得实际上是一种前瞻视野,预料到某个时期内软件要应对的变化并为此提前作准备。”

    绝对不同意这点,如果你要预料到某个变化,它就应当出现在需求说明里面。

    软件不存在模糊地带,80%的项目问题出在需求这个环节。

  21. 2011年6月27日15:23 | #21

    大家的回复好像没有看懂Jim和bob在争论什么。也许是我写得太乱了。我再总结一下:

    1)Jim说,软件的开发应该是做充分的业务思考和分析,才能得到软件架构,然后在这个架构上进行UT,而不是用use case产生架构。

    2)Jim说,软件的架构进化都没有错,但不是从test case来的。有test case的时候有代码,有代码就有bug,你不可能用test case测试所有的情况,test case耦合代码太重。而使用CDD会更好一些。

    3)Jim的意思是,TDD这种方法即不可能导致好的软件架构,也不可以让你测得更好。如果你不明白业务的本质,你没有好的设计能力的话,没有软件架构的话,你的项目就会运作在巨大的风险中。

    4)懂得做软件开发的人,已经在做正确的事了。而敏捷社区想要用TDD来定义这个专业化的事,Jim认为太扯了。

  22. cxu2003
    2011年6月27日15:29 | #22

    博主是赞同上面的观点了?

    • 2011年6月27日15:34 | #23

      我不知道你在问我同意哪个观点,我只是觉得大家可能读偏了。

      另,我同意的是Coplien的观点,就像我在和原来那个贴子里和大家争论的一个“开发WOW的示例一样”——Thoughtworks的人看到的WOW是一个个对象,而我看到的根本不是对象。就像本文中 Coplien 说的——“你们以为储蓄帐号是对象,其它他复杂的多的多”。

      看看这个争论,Coplien给了很多的实际的例子。Bob大叔从头到尾只在说方法论。这就是为什么我痛恨不谈业务不谈技术,只谈方法的horse shit了。

      还是那句话——“好的方法应该来自团队内部,宏观一点,也就是来自全世界的程序员,而不是来自某个公司,公司必然有其商业目的。

  23. Mic
    2011年6月27日15:40 | #24

    @Nogard
    大家都好偏激, 没有探讨的精神,搞一言堂

    “如果使用TDD的过程中,只强调UT并忽略前瞻性的设计,那肯定就会如博主提到的那样,走进死角最后crash掉”
    难道TDD就是在一堆UT cases前面从空白文件开始编码?难道TDD就是通过了所有测试以后就Release搞定?太好笑了,也许你们对TDD或者敏捷的认识就是如此才有这种观点。 我根本就没有兴趣褒贬这些方法,只是提醒博主如此反复地一味贬低他人,是不是心胸狭隘了点。

    “所以你们坐而论道,不拿出实际的case出来,都是horse shit”
    是在佩服你实事求是的科学精神。

    “也无法说明TDD或者什么的就是对的”
    根本就没有要证明TDD是对的。难道一种方法不是对就是错吗。

    “所以你们吵什么呢?这种事情就让成败论英雄吧”
    没有人在吵,起码我没有。还有事实是敏捷很有人气,TW是家不错的公司。

  24. Mic
    2011年6月27日15:57 | #25

    @陈皓

    皓哥,我是很同意你的观点,也深信你的能力的。但是,我只是想说不要如此偏激地看待方法论。xDD还是什么方法只是完成一项目可复制的,可控制的一种具体步骤, 没有人说xDD可以实现完美的架构, 也没有人说xDD就是好的方法。没有人说用xDD的方法就要抛弃业务调查和不断的修正迭代。 况且完成一个产品,一个项目难道一定要实现最完美的架构才是好的产品吗。
    方法论的最主要目的就是在工程应用中可复制,可控制.而你们那些大师级的思想是很难复制和控制的。正是这样才需要一些方法去快速实现一些目的。
    “好的方法应该来自团队内部,也就是来自全世界的程序员”,你的观点我很认同,也是我自己的体验,但看似很具体,其实这也是空的,无法复制的,这是不如直接应用一些方法来的有效的地方。毕竟不是所有人都能成为大师的。

  25. 2011年6月28日15:01 | #26

    “他说代码在哪里,UT就跟到哪里,代码有多臃肿,UT就有多臃肿,而UT也是代码,也会有BUG,所以,其实这真是事半功倍。还有一个最有名的示例是ADA编译器,其使用了TDD,反而增加了代码中的BUG,因为你的代码多,测试就多,代码就更多,整个代码就太过臃肿。”

    这应该不是TDD的问题而是单元测试的问题吧,测试越完整,代码覆盖率越高,这个问题就越明显。

    • 2011年6月28日16:23 | #27

      我感觉我国的TDD能人众多,其软件专业化水平完全超过欧美,这是何等的盛世啊。可惜的是,我们在业务需求和技术上的能力的巨大差距,导致了我们今天还是在C2C和山寨。

  26. andy
    2011年6月28日17:33 | #28

    关于TDD/XP,Peter Seibel在 “coders at work” 中很多受访者讨论过,似乎普遍的观点是写testcase总归是好的,但是一定要TDD可能就过分了。

    非常同意Peter Novig的观点,很多程序,如果你本来就没这个本事去写,TDD/XP根本帮不了你,只会让你做更多无用功,如果你确实有这个能力写,那么写写testcase可以更好的帮你完成任务(大意如此)。他还举了个例子:他曾经写过一个程序(似乎是算数独?不记得了),贴在自己网站上,然后某个XP advocate写blog批评他的程序,然后说:“看我用TDD来写”。结果过了五六个iteration,写了一堆的testcase和接口代码,最后放弃了,很有意思。

    就我个人而言,大多数时候,我需要的不是静态的把一个个testcase写出来,放在文件里,而是一个read-eval-print-loop,一样可以帮助你设计接口,但免去了写倒霉的mock/stub这些无聊的东西。在不需要用mock并且使系统核心部分的地方还是会写unittest.

    大家还是去看看coders at work吧,非常好的程序员休闲读物,呵呵。

  27. 2011年6月29日01:51 | #29

    “看我用TDD来写”,很是霸气啊。我的感觉,TDD对于那些逻辑复杂但是输入输出的数据结构简单的东西,用起来当然是行云流水。可惜晚辈闲暇之时写的几个编译器,你说文法本来就那么复杂,就算是一行几十个字符的代码,产生的语法树也是一团糟,assert起来实在是只会让测试变得更乱啊。当然晚辈也不是不写测试,只是换了一种手法,用不严格的简单测试加上一点点人眼的劳动来保证自己的东西不至于出大乱子。所以说【光靠】TDD是干不出什么太好的事情的。倘若前辈们在用TDD的时候顺便加入了【其他方法】,那事情当然是不一样啦。因此,这coplien的观点就十分好,TDD可以用,但不能作为冲锋陷阵的带头兵器啊。架构自然是不能从TDD出来的,TDD出来的只是接口。在一个接口后面,可以有好的架构,可以有坏的架构,都可以完成这个接口。因此TDD实在是深入不到这一层的。料定陈皓同学最近多次发文涉及TDD,应该也是心有体会。至于看官们,显然不必拿coolshell当权威,自然也不用火药味那么重了。

  28. andy
    2011年6月29日10:09 | #30

    哈哈,找到一点链接,那位XP/TDD advocate原来是Ron Jeffries.

    http://gigamonkeys.wordpress.com/2009/10/05/coders-unit-testing/
    http://www.infoq.com/news/2007/05/tdd-sudoku
    http://ravimohan.blogspot.com/2007/04/learning-from-sudoku-solvers.html

    Once again, domain knowledge(在这里是算法设计) is much, much, much more important than what methodology you follow.

  29. 2011年6月30日23:36 | #31

    @陈皓

    - 架构和TDD的关系是什么?它们是一个维度的东西么?两个正交的概念你为什么要掺和在一起?做TDD就没有架构设计阶段了?谁告诉你的?
    - Bob大叔喜欢咆哮,他是想引起大家的注意。他冷静的思考你可以看看他的《敏捷软件开发-原则、实践、模式》还有《Clean Code》,请问你反驳他哪一点?你妖魔化Bob大叔有意思么?我觉得你就是哗众取宠。
    - 你对TW如果不服气你可以点名去指正。说实话世界上能有足够多一线程序员做咨询的公司你还能找到几个?Relevance、Pivot labs和ThoughtWorks在业内都是以敏捷实践闻名的,难不成你绝得这种方式不靠谱,而IBM和埃森哲那套更靠谱?

    我把我对TDD的辩护意见写在我的博客了:
    http://www.diamondtin.com/2011/why-i-support-tdd/

  30. 2011年7月15日09:37 | #32

    ,Knet在解释XP的时候,在他的书131页的位置说过

    好多kent拼成了knet,博主自己ctrl+F一下吧~

  31. baibaichen
    2011年7月22日11:21 | #33

    Jim的说法没错,但TDD本身没问题,关键是你怎么用。

    UI比较难测,但你看google chrome 也有UI单元测试的代码。

    通常TDD,UT在初期看不到效果,测试都会通过,这也正常,因为要是不通过,你也不会check-in代码了。
    后期如有需求变了,UT的效果就出来。至少它会让你回忆起某些你已忘记了的细节。

    UT和设计之间的平衡那是人决定的。

  32. shaopeng
    2011年8月17日16:59 | #34

    这篇文章和评论的信息量很大,看了很久才看完。对TDD有了更全面的认识。很多问题不讨论是很难真正理解的。

  33. numen
    2011年10月19日21:54 | #35

    如果想要应付项目了事,可以用TDD,其实用什么方法轮都无所谓,应付本来就是一种商业策略。

    但是要开发真正有价值能重用的东西,没有架构做基础是肯定不行的。我的经验大型项目需要有专门的架构设计阶段,而且架构原则会引导和约束用户需求。

  34. jnj
    2011年10月20日08:34 | #36

    “架构原则会引导和约束用户需求” what a bullshit!?

  35. numen
    2011年10月27日18:50 | #37

    JNJ: Just see your comments. Wonder if you had been engaged in blueprint design or high level architecture design.

  36. jnj
    2011年10月28日05:35 | #38

    Hi numen, yes I have. My point here is that business requirements can’t get constrained by architecture principles, because they think technology is supposed to help them grow their business, instead of the other way around. Why do you want to constrain what the business wants with your architecture or design? What really limits business requirements is resources (time, budget, and etc), and the business is quite reasonable in this sense. I’m just arguing on this point “约束用户需求”.

  37. jackhuang
    2012年3月16日22:21 | #39

    一个人说大家要遵守交通规则,另一个人跳起来说:你说的不对!人不吃饭时要饿死的!

  38. yuan
    2012年12月9日00:37 | #40

    “不是吗?大多数人都知道怎么开发软件,而不是TDD才是专业化的软件开发。”

    我比较同意另一句话:大多数程序员不会写代码。

  39. yuan
    2012年12月9日00:45 | #41

    读完了我的感觉就是一个由于别人乱给 TDD 下定义导致某大牛反感所谓的 TDD,引发了与另一个使用 TDD 的大牛之间的争论:实际上他们之间没有太大矛盾。

  40. 2013年7月29日09:16 | #42

    “Coplien说Bob大叔创建了不应该创建的二元论。他说代码在哪里,UT就跟到哪里,代码有多臃肿,UT就有多臃肿,而UT也是代码,也会有BUG,所以,其实这真是事半功倍。”

    文中“事半功倍”应该是“事倍工半”的意思吧?

  1. 2011年7月11日13:38 | #1
  2. 2011年7月11日22:35 | #2
  3. 2011年7月25日05:41 | #3
  4. 2011年7月25日16:03 | #4
  5. 2011年9月2日15:51 | #5
  6. 2011年10月25日09:40 | #6
  7. 2011年10月26日10:59 | #7
  8. 2011年10月29日17:01 | #8
  9. 2013年8月29日21:06 | #9
  10. 2013年12月3日22:34 | #10