`
一蓑烟雨任平生
  • 浏览: 52464 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论
阅读更多
上次是敏捷,这次说说TDD。

TDD现在的路子不对,讲的再怎么天花乱坠也还是单元测试的路子,实际上在业务系统的开发中作用未必如所说的那么明显,否则这么好的东西也不可能推广的这么困难。
业务系统的核心是数据,开发过程是数据驱动的,在一开始做开发设计的时候,用例和场景应建立在数据的基础之上,粒度在服务这一层就够了,然后逐步细化。单元测试这个层级粒度太小,做得再多,也不能保证一个完整业务跑的是不是正确。

那么什么才是正确的TDD呢?站的角度要高一点点,层次也要高一点点。
TDD不应该用现在这样的套路,而是应该基于功能,将测试数据和业务代码、测试代码分开,在项目的一开始就由业务顾问负责,组织设计、开发人员等等等等一起来设计、完善测试场景和测试数据,并且随时和业务客户来审核验证。
测试场景和测试数据是TDD的关键,而不是写多少的测试代码。
分享到:
评论
28 楼 范三山 2010-03-05  
恩,我发现我最近在做的仅仅是单元测试 而不是tdd
27 楼 daquan198163 2010-02-03  
taowen 写道
一概而论TDD是很难讨论出什么有意义的结论的。不妨我们把TDD定义为:
1、针对Compilation Unit(也就是类和方法)的Unit Test
2、只管红绿条的节奏,无明确指导目标的重构。而所谓的“Design”会神奇地被“Drive”出来。
如果同意这个说法,那么这样的TDD是非常有害的。
(参见James Coplien 在2008年Oredev会议上的演讲“Agile Fine Tuning” http://archive.oredev.org/topmenu/video/agile/jamescoplienagilefinetuning.4.5a2d30d411ee6ffd2888000599.html)

关于第一点。针对编译单元级别的Unit Test很难真正起到什么正面的作用。相反会增加代码之间的耦合。因为Unit不光是和其他的Production code Unit耦合在了一起,还和Unit Test耦合在了一起。这样的耦合往往直接形成了重构的阻力。因为任何有现实意义的重构,都是在Unit之间调整职责。在这样的调整过程,很难保证compilation unit这个层面的接口是稳定的。让问题更加恶化的是对Mock的滥用。从而形成了一点重构红一片的现象。
我个人已经缺省不在编译单元这个层面做Unit test,除非它包含了确实自成体系值得一测的东西。但是这个并不是说不做Unit test。我们应该把对Unit的理解提升一点。一个Compilation unit往往不是自成体系的,它们需要和它们的协作者拼在一起才能完成一定的功能。如果分包做得好,实现一个功能的相关的Compilation unit应该内聚在一个包内。而这个包才是真正值得测试的Unit。

关于第二点,参见Rebecca Wirfs-Brock 关于What drives design的演讲http://www.infoq.com/presentations/What-Drives-Design-Rebecca-Wirfs-Brock。一开始TDD的D是Development。有印象是Jimmy Nilsson这个很cuo的家伙把这个D换成Design的。没有任何证据表明TDD会减少coupling增强cohesion。倒是有很多实践表明,TDD很容易让代码写成procedural的。

可不可以理解为:
尽量写package或模块级别的集成测试;
测试尽量黑盒,只关心输入输出,不关心内部逻辑;
设计也不要指望靠测试来神奇的驱动出来,还是要靠合理的使用设计模式、遵循OO原则。
ps:该mock的地方还是要mock,比如外部通信。
26 楼 wsgwz_2000 2010-02-03  
一蓑烟雨任平生 写道
我现在知道自己酒后犯了一个什么样的错误了,TDD这顶帽子已经被戴在固定的脑袋上,可是咱重新起个什么名字好呢?TDDD=测试数据驱动开发,TD3,嗯,这个名字不错。


可以和这位合作下:
ronghao 写道
数据驱动测试

http://www.iteye.com/topic/542452


DTT -> TD3 
25 楼 强强爱妍妍 2010-02-03  
一蓑烟雨任平生 写道
要这么说就没劲了。
这么多年一直在项目一线,见过的门派多了。各家招式不一样,不会打还不能评价?

不过,我还是真的好奇,真正的TDD怎么做?


不是段誉也可以是王语嫣哦
24 楼 taowen 2010-02-02  
一概而论TDD是很难讨论出什么有意义的结论的。不妨我们把TDD定义为:
1、针对Compilation Unit(也就是类和方法)的Unit Test
2、只管红绿条的节奏,无明确指导目标的重构。而所谓的“Design”会神奇地被“Drive”出来。
如果同意这个说法,那么这样的TDD是非常有害的。
(参见James Coplien 在2008年Oredev会议上的演讲“Agile Fine Tuning” http://archive.oredev.org/topmenu/video/agile/jamescoplienagilefinetuning.4.5a2d30d411ee6ffd2888000599.html)

关于第一点。针对编译单元级别的Unit Test很难真正起到什么正面的作用。相反会增加代码之间的耦合。因为Unit不光是和其他的Production code Unit耦合在了一起,还和Unit Test耦合在了一起。这样的耦合往往直接形成了重构的阻力。因为任何有现实意义的重构,都是在Unit之间调整职责。在这样的调整过程,很难保证compilation unit这个层面的接口是稳定的。让问题更加恶化的是对Mock的滥用。从而形成了一点重构红一片的现象。
我个人已经缺省不在编译单元这个层面做Unit test,除非它包含了确实自成体系值得一测的东西。但是这个并不是说不做Unit test。我们应该把对Unit的理解提升一点。一个Compilation unit往往不是自成体系的,它们需要和它们的协作者拼在一起才能完成一定的功能。如果分包做得好,实现一个功能的相关的Compilation unit应该内聚在一个包内。而这个包才是真正值得测试的Unit。

关于第二点,参见Rebecca Wirfs-Brock 关于What drives design的演讲http://www.infoq.com/presentations/What-Drives-Design-Rebecca-Wirfs-Brock。一开始TDD的D是Development。有印象是Jimmy Nilsson这个很cuo的家伙把这个D换成Design的。没有任何证据表明TDD会减少coupling增强cohesion。倒是有很多实践表明,TDD很容易让代码写成procedural的。
23 楼 抛出异常的爱 2010-01-29  
一蓑烟雨任平生 写道
我现在知道自己酒后犯了一个什么样的错误了,TDD这顶帽子已经被戴在固定的脑袋上,可是咱重新起个什么名字好呢?TDDD=测试数据驱动开发,TD3,嗯,这个名字不错。

如果测试开发成型了.
我想我会改进框架.
来提高效率
或者自己写个轮子.
反正能少写点代码就少写点

数据开发这种事还是由于技术水平没到那个台阶面前.

好高骛远的达到thoughtworkes的tdd水平

我所在的小组在没人带领的条件下
自发完成用三四年也是很有可能的.

当然 最大的可能是下个月底拆团重建
22 楼 一蓑烟雨任平生 2010-01-29  
我现在知道自己酒后犯了一个什么样的错误了,TDD这顶帽子已经被戴在固定的脑袋上,可是咱重新起个什么名字好呢?TDDD=测试数据驱动开发,TD3,嗯,这个名字不错。
21 楼 抛出异常的爱 2010-01-28  
chanball 写道
蓝皮鼠 如果有实际的例子讲解一下就更好了,最好选个复杂一点的

复杂了就T不了了

一般要是真的很复杂....
以至于我不能快速写出测试的话
我都不写测试的
(真的不愿意写就不写)

我第一次TDD是由于EJB启动一次需要十多分钟...
如果你的项目启动一次需要那么长时间用一次TDD就会爱上它

TDD还有好处就是改的快
只要先把测试加了
之后就不想别的只要改代码让绿条出了就OK了
不用提心掉胆的改代码 .

比如一个工具
要输入两个时间
输出一个list 里面是
这两个时间之间的
自然天的启止时间
用来查寻

我就把页面上传过来的东西向里一放
把预想值一写
什么边界
什么入参的正确性啊
什么个数多了少了
什么都 不管了
只要预想对了
代码 就对了
脑子不用记那么我东西.

当然这个工具写完了之后
在用的时候还是有bug
别人踢回来后
我又加了一个测试
就是那个bug所真存在的数据
改改就绿了.
这要放以前
读这代码 得用半天时间
找到问题不得再用半天时间?
改了之后测以前的功能没被破坏再来一天
加上写测试改这个bug用了30分钟.
我还能保证以前的功能 没被 破坏.

现在除了页面拦截器不太会测还在用着原始的方式
写好了再看其它都尽量去写测试了.
有些特别少写的代码我都不太会测试
主要是人懒....
20 楼 chanball 2010-01-24  
蓝皮鼠 如果有实际的例子讲解一下就更好了,最好选个复杂一点的
19 楼 chanball 2010-01-24  
蓝皮鼠 说得不错,TDD大概了解一点,但是没实践项目实践过。而且很多公司不愿用TDD,大概就是觉得它浪费时间,而且对程序员也要进行规范。
18 楼 蓝皮鼠 2010-01-24  
不要一开始用自上而下的方式去推TDD,最好自下而上。03年底我花了几周的晚上业余时间把《测试驱动开发实用指南》(影印版)(jolt获奖的,当时中文版还没出)里面的例子全部手中输入并执行了一遍,感觉帮助比较大。

然后在我自己负责的项目里面,完全的按照TDD的方式来进行设计和开发,由于当时人手比较少,只是我一个人在用,所以没有什么人反对。感觉真的很爽。那个项目基本没有多花什么时间,但是效果非常好。

后来觉得开发人员最好自己严格的按照TDD的方式有过至少一次的项目开发,然后再决定开发的方式,就算以后不用TDD,但是设计和开发思路一定会受到正面影响,

另外项目中有部分关键模块采用TDD还是比较现实的,我希望大家不要顾虑太多,光说不练。还有就是从小处做起,不要搞的好象很大件事情,增加不必要的麻烦。

附图是一点证据,呵呵
17 楼 一蓑烟雨任平生 2010-01-24  
哦?怎么做?
16 楼 gty509 2010-01-24  
Tdd可以作为开发文档的一部分。
15 楼 diogin 2010-01-24  
局外人的观点:

谈了这么多年的 TDD,怎么感觉这么多人还是在盲人摸象?每个人都看到了 TDD 的“一条腿”,然后在论坛上说“TDD 应该是这样的”,“TDD 应该是那些的”,“TDD 像棍子”,“TDD 像堵墙”,等等等等。。。。

我想问的是,既然 TDD 这玩意这么模糊、这么难以分辨,何必苦苦去“实践”?莫非各位都抱着“皇帝的新装”心态?
14 楼 photon 2010-01-24  
一蓑烟雨任平生 写道
看来还是我没有说清楚。
有机会和蓝皮鼠、frostred 、mock聊聊。

我极度怀疑能聊明白,或者聊之前应该把kb的tdd explained里边的两个例子做一遍。

引用
TDD不应该用现在这样的套路,而是应该基于功能,将测试数据和业务代码、测试代码分开,在项目的一开始就由业务顾问负责,组织设计、开发人员等等等等一起来设计、完善测试场景和测试数据,并且随时和业务客户来审核验证。

tdd不难,但是要达到楼主提到的要求,确实不是一件容易的事情,至少je中还没有看到做的很好的例子。如果有人在这方面做得很成功,并且不侵犯受保护的知识产权,希望能分享一下经验。
13 楼 photon 2010-01-24  
seen 写道

也许可以换个角度来想:是哪些人在推广tdd,以及他们为什么要推广tdd。

另外,我的经验是,任何一个需要花费1人周以上精力来解决的bug,统统不是tdd能够发现或者预防的。

我很赞同,只是想补充一点,不能因噎废食。
12 楼 一蓑烟雨任平生 2010-01-23  
看来还是我没有说清楚。
有机会和蓝皮鼠、frostred 、mock聊聊。
11 楼 蓝皮鼠 2010-01-23  
我不是说TDD方向偏了,是说觉得TDD很难用的时候,基本都是自己把问题搞复杂了。
实际情况中,小块的代码,叫class或者method都可以,都是解决简单问题的,如果觉得连unittest都很难做,那应该是把很多其他东西考虑在一起来。

另外说一下,实际情况我也不是每个项目都用TDD,只是自己必须搞好的地方才用,个人感觉TDD对程序设计要求比较高,没有经验(不是指TDD经验,而是指程序设计经验)的程序员最好有人指导。有经验的人如果搞不清楚TDD,我觉得不太可能。
10 楼 amonlei 2010-01-23  
gigix 写道
引用
TDD这块我确实没有什么实践

我一直很好奇,为什么人们能对自己“没有什么实践”的东西有那么多“觉得”
嗯,勇气可嘉,虽然在论坛说说话其实也用不着什么勇气

支持!看到这一句,基本上我就不想往下看了。
9 楼 frostred 2010-01-23  
没错,TDD是低层次的东西。它关注的是class/method这一层次的设计和实现。这有什么不对吗?你为什么觉得它的方向偏了呢?你又有什么其它方法可以保证代码的质量吗?

当然,我们开发软件,最终的目的是要一个可以正确运行的系统。代码的质量好,并不能证明它就一定正确。但它正确的可能性更大一些,而且即使不正确,好的代码修改起来也更容易一些。

其实敏捷的核心就是人和代码 - 通过程序员写高质量的代码来完成系统的构建。而不是开发前海量的设计/文档,开发后海量的测试来完成。敏捷的过程不是不重视设计和测试,它其实更重视,但它是在开发的过程中来完成,而且其中相当大的一部分是由程序员来完成的。

相关推荐

    单元测试与TDD实践

    单元测试与TDD实践 **一、单元测试之测试目的** 单元测试,作为软件开发过程中的重要环节,其核心目标在于确保代码的质量、可维护性和可扩展性。它通过独立测试软件中的最小可测试单元,如函数或方法,来验证其...

    TDD测试驱动开发

    测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,强调在编写实际功能代码之前,先编写测试用例。这种方法的核心理念是“先写测试,再写代码”。TDD通过引入测试来引导软件设计,使得开发过程...

    wifi TDD 时间同步及分时调度方案

    "Wifi TDD 时间同步及分时调度方案" Wifi TDD 时间同步及分时调度方案是一种在 Wifi 网络中实现时间同步和分时调度的解决方案。该方案主要依赖于 Wifi 网络的 beacon 帧来实现时间同步和分时调度。 时间同步是指在...

    抑止TDD noise 的措施

    ### 抑止TDD Noise 的措施及解决方案 #### TDD Noise 概述 TDD (Time Division Duplex) 是一种常见的无线通信技术,在移动通信领域应用广泛。然而,在实际使用过程中,用户可能会遇到由TDD Noise 引起的音频质量...

    phpunit-TDD驱动开发

    ### 使用PHPUnit进行TDD驱动开发 #### 一、引言 测试驱动开发(TDD, Test-Driven Development)是一种软件开发方法论,它要求在编写实际功能代码之前先编写测试用例。通过这种方式,可以确保代码的质量,并且有助...

    UMTS-TDD手册

    ### UMTS-TDD 手册知识点解析 #### 核心知识点概述 本文档主要针对的是**NS2网络仿真软件**中的**UMTS-TDD**(Universal Mobile Telecommunications System - Time Division Duplex)仿真方法进行了深入细致的介绍...

    Test Driven: Practical TDD and Acceptance TDD for Java Developers (PDF英文版)

    《Test Driven: Practical TDD and Acceptance TDD for Java Developers》是一本专注于Java开发者进行测试驱动开发(TDD)和验收测试驱动开发(Acceptance TDD)的专业书籍。这本书以PDF英文版的形式提供,旨在帮助...

    GSM_TDD板振说明及分析解决方法总结.docx

    在移动通信领域,GSM TDD(Time Division Duplexing,时分双工)系统是一种广泛应用的技术,其中“板振”或“板震”问题是一个常见的工程挑战。本文将深入探讨GSM TDD板振的成因、分析方法以及解决策略。 首先,板...

    GSM TDD noise分析

    "GSM TDD 噪声分析" GSM TDD 噪声是一种常见的干扰现象,发生在 GSM 通信系统中的射频部分。这种噪声的产生是由于天线辐射出的射频能量和 PA 突发工作时带动电源的干扰。为了减少这种噪声的影响,我们可以采用一些...

    TDD-CDMA_for_Wireless_Communications

    ### TDD-CDMA在无线通信中的应用 #### 一、引言 TDD-CDMA(时分双工-码分多址)是无线通信技术中的一个重要分支,它结合了时分双工(TDD)与码分多址(CDMA)两种技术的特点,为移动通信系统提供了高效的数据传输解决...

    测试驱动编程 TDD 实例

    测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,它的核心思想是“先写测试,再写代码”。TDD强调在编写实际功能代码之前,先编写能够失败的单元测试,确保测试覆盖了预期的功能需求。这种...

    TDD 测试驱动开发 文档 详细

    测试驱动开发(Test-Driven Development, 简称TDD)是一种软件开发实践,强调在编写实际代码之前先编写测试用例。这种方法的核心理念是通过编写能够失败的测试来定义需求,然后编写足够的代码使测试通过,最后重构...

    tdd_by_example.pdf

    ### 测试驱动开发 (TDD) 知识点解析 #### 一、TDD概念与原理 **测试驱动开发(Test-Driven Development, TDD)** 是一种软件开发方法论,其核心思想是在编写功能代码之前先编写测试用例。这种方法能够确保软件的...

    Ruby-TDD实战TestDrivenDevelopmentinAction

    **Ruby-TDD实战:Test Driven Development in Action** 在软件开发领域,Test-Driven Development(TDD)是一种编程实践,它强调先编写测试用例,然后编写满足这些测试的最小功能代码。Ruby作为一种动态、灵活的...

    Laravel开发-tdd

    【Laravel开发-TDD(测试驱动开发)】 在软件开发领域,TDD(Test-Driven Development,测试驱动开发)是一种编程实践,它强调先编写测试用例,再编写实现功能的代码。Laravel,作为一款流行的PHP框架,高度支持TDD...

Global site tag (gtag.js) - Google Analytics