《测试驱动开发应用实践》讨论记录

《测试驱动开发应用实践》讨论记录

 

Design & Pattern团队第二次交流会

主题:测试驱动开发应用实践

日期:本周星期五(2005年1月7日)晚20:00——21:00

地点:团队聊天室

 

Design & Pattern团队举办《设计模式在软件开发中的应用》讨论后,收到众多对设计模式感兴趣的网友的好评。根据大家的需求本次交流会中大家讨论当今流行的开发方式测试驱动开发(Test-Driven Development,TDD)。大家谈到了什么是测试驱动开发?怎样来做测试驱动开发?以及我们工作中开发方式与测试驱动开发的异同。虽然本次参与的人不多,但由于大家都对TDD非感兴趣,所以讨论同样很激烈,没有时间参加的朋友应该感到可惜哟,不过好好看完下面的内容,然后发表你的意思,我们就可以延伸我们的讨论,让我们的团队越办越好,让大家都能感受到集体的温暖。由于没有dudu和wayfarer的参与,本次讨论还是显得有点乱。由于以上原因,所以本次聊天记录我只作了简单整理,尽量保持各位网友的原话,以便大家看后容易理解。另由于本人水平有限,整理的不好还请大家指点。

测试驱动开发是一种开发方式:

n          你要维护一套详尽的程序员测试集

n          除非存在相关的测试,否则不编写任何产品代码

n          首先编写测试

n          由测试来决定需要编写怎样的代码

 

以下是聊天记录:

春鱼      先举一下手吧。熟悉TDD的:  

春鱼      Me ×  

蝈蝈      我熟悉一点,做过半年的XP开发,不过并不理想。

jeseeqing    我在項目中應用過TDD,效果還可以  

idior    我没有实战过  

蝈蝈      哦,那jeseeqing也应该有很多经验了  

jeseeqing    實踐過以下原則:1 Test First  

ocean    我们的测试一直做的比较烂  

蝈蝈      测试驱动开发--------实用指南,这本书也写的不错  

jeseeqing    2、Continue Integrated    (持续集成)

ocean    通常大家认为的bug在我们团队中都不作为bug看待,嘿嘿  

春鱼      通常大家认为的bug在我们团队中都不作为bug看待:怎么理解?  

Idior    jeseeqing 说的没错  

Idior    加上不断重构  

ocean  比如有时因为用户的输入带有攻击性,对于我们的很多程序可能直接就报一个系统错误出来了,没有友好的报错界面  

jeseeqing     TDD可以減少bug  

ocean    这个报错界面可能就是aspx自身出错的时候的那种  

纯爷们   我没有实践过TDD,  

idior    Tdd用在开源项目很合适  

蝈蝈      有了TDD同样不能没有集成测试这一环节  

毒龙     最近想在项目中使用单元测试,大家提点建议  

ocean  我们现在的原则是“如果是用户恶意的输入而导致的程序错误,我们不提供友好的报错界面,只保证错误的输入不会对正确的数据产生影响”  

ocean    要不然我们的测试根本做不过来  

毒龙     我从网上找了一下,但关于数据库相关的测试比较少  

春鱼     这样处理不好吧  

ocean    程序也会写的复杂  

idior    ocean 谈的和tdd没太大关系  

蝈蝈    其实不知道大家有没有看过陈叙远的NUNIT高极应用,web,winform都可以测试的,还有可以模拟测试  

jeseeqing    to ocean:惡意的輸入你們有什麼原則  

ocean    不会影响数据正确性  

ocean    比如一个id=3,有些人可能输入id=3;delete...--之类  

纯爷们  大型的数据库应用如何采用TDD啊?我们刚开始还想那么做了,但是后来觉得不可能,还不如操作后用查询分析器呢,是不是有点弱智?  

idior    ocean 谈的和tdd没太大关系 大家不要深究了  

idior    陈叙远那个还没看  

ocean  我们不会让这个语句产生delete的效果,但是转换数字的时候可能直接就报了一个exception出来  

ocean    ok,不谈我的了 。大家谈正题吧  

idior   不过肯定要看的  

毒龙      不会没有人理我吧  

蝈蝈      idior说的对,那属于SQL注入式攻击的内容  

毒龙      想测试,但数据库的应用不好测  

idior    数据库测试我就知道常常会用mock  

jeseeqing    數據庫的確不好測試,不好構建測試環境  

蝈蝈     请大家谈谈TDD的测试与单元测试有什么不一样  

纯爷们  呵呵,大家应用TDD在什么项目上啊?我觉得平台级别的,类库级别的还可以,数据库应用不大容易啊!  

春鱼      TDD是不是现有测试后开发  

ocean    我们还不知道tdd的测试到底是什么样子的  

jeseeqing     TDD中的主要測試就是單元測試呀  

ocean    有谁用简单的几句话扫扫盲  

蝈蝈    我觉得我们需要测试主要是对象的行为,至于持久存储在哪里,我们并不关心,所以实际当中并不需要过多去测试 insert,update,delete之类的方法  

纯爷们   单元测试是TDD的实现基础吧,我是这么理解。  

idior    纯爷们 你对数据库开发还停留在er图上吧  

jeseeqing     TDD與普通開發方法不同的首先寫單元測試,再寫代碼來通過此測試  

毒龙      我只想从Nunit开始,先做了代码,再写测试  

春鱼      TDD的意义在哪里?  

纯爷们   哈哈!!idior,你答对了!  

jeseeqing    先寫了代碼,再寫單元測試,就沒人太大的意義了  

毒龙     但总得一步步来吧,项目组中每个人不一定都能理解此思想  

蝈蝈    如果确实需要测试的话可以用complus来做,让做完数据库操作之后回滚数据  

idior    你的那篇随笔后有人的回复不错  

纯爷们   我们没有成熟的O/R M框架  

idior    对了  

idior    如果有了orm框架,数据库的测试就不一样了  

毒龙 idior, 为何?  

纯爷们   不好意思,我刚才跑题了!  

idior    当然tdd是不太考虑什么压力测试之类的  

蝈蝈      压力测试不属于tdd方法里面的内容  

毒龙      我的NUNIT应该不跑题吧?  

蝈蝈      需要做测试肯定少不了nunit  

idior    对的  

纯爷们  我们现在的测试基本上是靠robot来模拟操作,然后去看数据库里面有没有记录,或者检查完整性,挨!根本没什么TDD!  

毒龙     可以讨论我的“如何进行数据库应用的测试?”这个主题?  

蝈蝈    在tdd中我们把测试叫做程序员测试,它与我们通常所说的单元测试是不一样的  

ocean    差别在什么地方?  

ocean    程序员测试-》单元测试  

蝈蝈    纯爷们说的对,这样测试是没有达到TDD的要求的,因为它不可以达到自动化测试

Allen Lee既然主题是测试区东开发应用实践,那么不如先讨论一下“使用TDD的意义何在”,也就是我们为何热心于TDD吧。(个人建议)  

Idior    数据库的测试不是tdd的主题  

蝈蝈      就是说测试代码只是对于当前有用,不能为以后的重构作保障  

毒龙      好吧,TDD的意义  

idior    tdd的测试集中在单元测试  

ocean    我不知道tdd有什么意义  

毒龙      为了重构,持续地重构  

idior   就是说测试代码只是对于当前有用,不能为以后的重构作保障   有问题  

毒龙      为了实现每日重建  

纯爷们    是啊,我现在的理解是TDD可以使的代码的更改通过自动化的回归测试马上得出结果,避免大量的人力投入,而我们现在的回归测试是相当的耗时的  

做人要厚道   为了实现每日重建,能做到吗?   

idior    纯爷们 你的理解有问题  

ocean  “我现在的理解是TDD可以使的代码的更改通过自动化的回归测试马上得出结果”这个过程是怎么实现的呢?  

毒龙    我们的项目组现在想改底层代码,但受影响的地方很多,没有TDD,真不敢改!  

纯爷们  应该说重构会有一定的风险,因为不能保证重构后代码的正确,但是有TDD保证是不是可以验证重构后代码仍然正确呢?  

idior    不是为了测试  

idior   TDD 很重要的一点是测试"驱动"开发!!!  

Allen Lee    那么,综合大家的想法,TDD的一大重要意义就是Build和Test,除此之外,你们觉得TDD还有没有别的意义呢?  

idior    TDD 很重要的一点是测试"驱动"开发!!!  不是为了测试  

蝈蝈    当然是每次重构或修改添加新的代码的时候运行一下所以的测试,如果通过表明我们做的没有问题,如果不通过我们需要修改程序来使得我们的测试通过   

毒龙     没有TDD的build后的结果只能是一堆垃圾  

蝈蝈    我觉得测试驱动开发最大的好处在于它让你先了解了需求,有了明确的需求你才能写出测试代码,有不能通过的测试代码你才知道怎么来写程序保证测试代码通过  

毒龙    最终改善了代码的质量,提高了程序的稳定性  

ocean  但是有时的单元模块更改不是因为bug修改,而是需求更改,这是可能单元模块的功能发生了一些变化,这样原来写的测试也要跟着改变吧,不能说再用原来的测试运行一遍吧  

idior   根据需求产生测试案例,根据测试案例产生测试代码,为了使测试代码通过产生源程序    

毒龙     谁来把意义总结一下?  

蝈蝈    当然,当需求变了,我们首先需要改变测试代码,运行不能通过,再来写让测试代码通过的程序,这就是TDD  

纯爷们  哦,难道我的理解错误了,我理解的测试驱动开发也是先根据需求编写测试代码啊,而这些代码的编写就是为了以后的代码构建,以及重构或者修改还能够满足之前的去求啊,是不是有问题啊?  

Idior   对需求变化导致测试案例的变化,从而导致测试代码的变化,最终导致源代码的变化  

Idior    纯爷么你错了  

ocean    idior这么一说我到是比较清楚了  

纯爷们   那我好好学习了  

蝈蝈     有人做过nant吗  

Allen Lee    我觉得TDD的一个很重要的意义,就是给我们界定一个预期的结果,它使我们知道我们的东西是如何被使用的(需求与设计),然后就是我们通常认识的Build && Test。  

Idior    是用过吧  

Idior    Allen Lee说的不错  

蝈蝈     持续集成也是TDD的一个重要环节  

毒龙      用过ant, 但那时没有用Junit  

ocean    我觉得Allen Lee说的不错  

idior    测试代码就是你所编模块的使用代码  

纯爷们   对了,我问个问题,做TDD要不要测试案例完全覆盖需求啊?  

毒龙     现在不小心转到.NET阵营了  

idior    应该要的  

ocean    测试用例自然应该完全覆盖需求  

纯爷们   不知道是不是我们公司做的太不规范的,测试用例的覆盖率往往低于需求:(  

Allen Lee    我觉得不可能完全覆盖需求,因为需求总是在变化,但我们有必要对需求进行排序,覆盖最重要的需求,实现增量开发。一来可以避免提交压力,也可以确立核心需求和应对派生需求。  

Idior    根据需求产生测试案例,根据测试案例产生测试代码,为了使测试代码通过产生源程序,对需求变化导致测试案例的变化,从而导致测试代码的变化,最终导致源代码的变化,从这两句话大家应该能明显看出驱动开发的痕迹  

ocean    需求变化要先改测试案例  

ocean    所以测试案例还是能够覆盖需求  

idior    测试用例的覆盖率往往低于需求  在tdd中就会导致代码的缺少  

蝈蝈    不一定的,测试代码也是不断的完善的,我们首先为了保证基本的需求通过会做的比较简单, 也就是说通过只写几个比较特殊的测试,然后让代码通过,之后不断的加强测试代码,使它尽量覆盖多的需求  

idior  对需求变化导致测试案例的变化,从而导致测试代码的变化,最终导致源代码的变化   

ocean    同意  

纯爷们  哦!idior说的我清楚了,其实我们出现那样情况的原因就是我们没有采用TDD,所以代码与测试代码脱节?我这样理解对吗?  

ocean    通常核心业务的测试用例比较重要  

蝈蝈     其实测试代码同我们的程序代码一样,也是经常不断的重构之后变的强壮的  

idior    纯爷么对啊!!  

ocean  偏远的功能(比如使用人员可能半年中都未必能用到一次的)就可以优先级低一点  

纯爷们   眼泪哗哗地,谢谢了啊  

毒龙     有哪位在项目中用了TDD?  

idior  不过我没有实战过,我也考虑的完全覆盖的可能性,也就是tdd是否应用于整个项目  

蝈蝈     大家认为一个类应当对应一个测试类吗?  

纯爷们   不知道大家是不是在实施TDD的时候QA与RD都是一个人啊?  

ocean  否则可能测试用例还没写完,需求就变了,然后就改测试用例,然后需求变,可能就永远到不了写代码的一步了  

idior    测试代码是由程序员自己写的  

ocean    我认为一个类对应一个测试类中的一个方法就可以了  

蝈蝈     xp成功的一点就是欢迎需求随时变化,即使到了项目结束期。  

idior    单元测试不是整个测试!! 

ocean    而一组功能(一系列类)对应一个测试类就成了  

纯爷们  我说一下我们的研发情况,QA与RD是独立的角色,想要QA在理解需求写出测试代码完全覆盖需求,然后用这个来测试RD的代码有点玄,不过不管怎么说这种思想是应该推进的  

idior    tdd只是unit test而已,大家别弄晕了  

蝈蝈     tdd不是单元测试,tdd是程序员测试   

纯爷们   我去,哎,我又错了。  

纯爷们   单元测试的话就比较好说了!  

Idior    tdd中的测试代码是由程序员自己写的而不是qa写的  

蝈蝈     单元测试是为了测试你的代码,是已有的代码  

纯爷们   因为就项目整体来说要团队协作实施TDD难度太高了,尤其是沟通的难度:  

idior    蝈蝈错了  

蝈蝈     但是TDD是测试类所表现的行为,是为了代码而写的  

毒龙     "tdd不是单元测试,tdd是程序员测试",这句话有问题  

idior    tdd先有测试代码  

idior    不是为了代码写的  

毒龙      真不知道“程序员测试”是个什么概念?  

idior    代码是为了测试代码写的  

蝈蝈    程序员测试和单元测试确实有很多相同的地方,但真的不是同一个概念,或许我用程序员测试不太恰当,为了说明与单元测试不同  

idior    代码是为了测试代码写的   

idior    代码是为了测试代码写的 !!!!!!!!!!!!!!!!!!!!!!!!  

ocean  突发奇想,测试代码能否直接写在代码类中?比如一个类中有10个方法,然后我增加第11个方法,这最后一个方法就是测试方法,这样程序员修改测试代码和程序代码的时候就可以直接一起写了,就像现在写注释写在程序中然后提取出来一样,减少不一致  

idior    这也测试驱动中驱动的含义  

毒龙     当然   

idior    ocean 这样好吗?  

毒龙     就是测试代码多了以后,就太乱了  

idior    要分离变化!!  

蝈蝈     这样维护起来很困难的  

纯爷们  我们有的方法就是这么写的,在底层类里添加方法来执行测试,一般都是写出文件,看SQL语句,不好意思,又说到数据库应用了!  

毒龙     我的一个类的测试代码是这个类的长度的10倍,是不是有点乱?  

ocean    其实没关系,完全可以通过条件编译,而且.net中方法都可以折叠  

idior    这个应该问题不大吧  

ocean    因为一个团队未必每个人水平都很好  

ocean    有些程序员可能改了代码但是忘了改测试代码,而现在这两个可以同时改  

纯爷们  大家推荐几本好点的TDD书,我聊天完后去整来好好看看,我觉得自己理解有问题。  

蝈蝈    其实我们应当把握一点就是nunit中有一个[setup]特性,这样我们就应当把具有相同的setup的东西放在同一个测试类中  

ocean    就想以前常常改了代码但是没改设计文档  

idior    martin flower的那本  

蝈蝈     关于程序员测试与单元测试及客户测试见《测试驱动开发---实用指南》第4页  

纯爷们   敏捷软件开发—原则,模式,实践 

毒龙 ocean又错了,不可能有改了代码而没有改测试代码的情况,因为测试会无法通过  

ocean    这样测试又没法通过的  

idior    敏捷软件开发是2003的大奖   

蝈蝈    敏捷开发中没有详细的谈到TDD的情况,也没有很好的例子来讲解怎么来做TDD  

idior    敏捷软件开发是本书,开头就是一个 tdd的完整例子  

蝈蝈     相信大家如果看过《测试驱动开发---实用指南》会有不一样的认识  

idior    测试驱动开发 确实是入门的好书!!!!!!  

纯爷们   蝈蝈 ,你极力推荐,我就看这本了:)  

idior    大家能否介绍一下各自都在做那些行业方面的应用或者产品?

毒龙     有谁有TDD的实践经验?书本上的知识使用起来不太容易  

蝈蝈    我说的完整是如何从需求到测试代码到程序代码到重构。敏捷开发也确实是本好书  

毒龙     我的团队中水平差别比较大,不太好上,项目压力又非常大  

蝈蝈    《测试驱动开发---实用指南》中国电力出版社,崔凯译的,美国的david astels和ron jefferies写的  

纯爷们  不知道你们的项目是什么样?我们的项目基本上时间卡的特别紧,管理水平以及人员的水平也有限,所以实施TDD任重道远。只能借鉴TDD的思想逐渐改善  

idior    纯爷们  tdd对人要求比较高  

纯爷们   恩,我们还基于ER图呢:)  

毒龙     使用C#的开发不超过2年  

蝈蝈     其实我们的项目也是这样的,中国的大多数软件公司也是这个现状的,因为要生存  

ocean    我觉得项目开发采用的方法要根据行业和开发的最终成品的特性来定  

ocean    不能走统一模式  

idior    基于ER图      

纯爷们  我想问大家一个问题,你在实施TDD的时候有没有记录编写测试代码和实际代码的时间?这个我个人觉得在实践中比较重要,因为直接影响Schedule  

蝈蝈    其实主要是商业利益第一,如果是搞学术研究,其实这敏捷,XP,TDD都很有意思的,可是实际的项目中确实很少公司这样做  

Allen Lee    看来大家对于“如何把TDD应用到自己的实际情况”这个主题很重视。那么,大家不如讨论一下“TDD实际应用时有什么条件”吧,也就是什么情况下我们应该使用TDD。(个人建议)  

ocean    确实是这样  

ocean    中国很少会拿出40%的时间来测试  

idior     wayfarer 认为open source时可以采用  

ocean    毕竟你不能亏本  

idior    我现在也赞同  

idior    估计他最近会发这方面的随笔  

纯爷们   有没有听说商业项目用TDD的?  

毒龙     to Allen Lee: 当需求可能经常变化时  

ocean    我认为做一个大型市场产品的时候必须用tdd  

毒龙     当项目周期较长时  

Allen Lee    换句话说,我建议我们讨论一下如何平衡TDD与项目以及商业之间的压力。  

ocean    因为这能保证质量  

蝈蝈    首先需要程序员的水平还可以,至少面象对象的思想很好,我们以前做XP失败的原因现在想想就是因为当初没有多人有对OO很熟  

idior   国外用的多  

ocean    如果是单独为客户开发一个项目则没有太大必要  

ocean    客户出了bug可以马上派人fix  

idior     symentac就玩xp  

ocean    产品就不一样,发布的话如果bug多多就麻烦了  

纯爷们  啊?大型的市场产品往往也有上市的压力,所以schedule也特别紧,哎!没有时间啥也干不成  

idior    ocean 你对tdd的理解还是不太对  

蝈蝈      我也非常建议开源的项目用敏捷方法来做  

idior    tdd重在dd 而不是t  

ocean    任何东西可能都时间压力  

ocean    但是风险不同  

ocean    大型产品出bug的风险和后期成本要比给客户定制的项目高的多  

蝈蝈      确实如此,我们做产品的更加压力大  

ocean     to:idior 多指教:),刚才讨论tdd和商业利益  

idior    时间差不多了,看来缺少了wayfarer等人,我们讨论的结果显的比较浅  

纯爷们   恩!有必要请idior把TDD的概念好好给讲述一烦,我怎么总犯低级错误呢:)  

蝈蝈    其实基本上大家聊的比较投入,但没有核心人物还是显得有点乱,总体还是不错的  

ocean  我们有的项目可能只有几千快,找两个人随便做一下就交工了的小项目,要是用tdd,岂不亏本,这些小项目可能只是程序员写完测试差不多就成了,可能都没有正是的测试团队去测试  

蝈蝈     我觉得idior这方面比较有经验  

毒龙     没有什么实质内容,主题比较分散,各人理解的不同意  

idior    纯爷么你没研究过而已   

ocean  测试驱动开发这个概念我以前了解过,倒是也能理解,只是不知道这个东东叫做tdd而已,嘿嘿  

毒龙    不如谈谈测试如何做  

蝈蝈    至少我们知道了TDD在我们工作中及的情况,还只是有概念,实际的应用不多  

纯爷们  是啊,我只知道个名词,说来丢人,所以才想听你讲讲啊,现在都讲究吃快餐!  

Idior    test driven develop  

idior    测试如何做 其实就不是tdd了,应该讨论test如何驱动开发  

idior    传统意义的test和tdd中的test是不太一样的  

蝈蝈    关于如何写好测试也是一个比较重要的东西,所以TDD难的一面也是能写好测试代码,程序肯定没有问题,但如果写不好程序员就不知道测试代码与程序的差别了  

ocean    tdd应该说是一种开发模型而不是单纯的交给我们怎么测试  

ocean    另外还要防止测试代码中也可能有bug  

idior   记住一点tdd中的test只是unit test 可能更好的把握  

idior    ocean对啊  

idior    tdd应该说是一种开发模型  

ocean    如果写的测试代码有bug,那么通过的代码肯定也有问题  

蝈蝈     对tdd是一种开发方式,与XP是不一样的  

ocean    也即把tdd当作一种测试类型就错了,而是当作一种开发模型  

ocean    只是这种开发模型是通过测试驱动的  

idior    蝈蝈 应该说xp包涵tdd  

ocean    也即开始说得,测试用例产生测试代码,测试代码产生实际的代码  

蝈蝈     这就是单元测试与程序员测试的差别所以  

ocean  开始我没搞清楚,这个东东我在以前接触过,刚讨论的时候大家都在说测试,所以我没反应过来  

idior    xp包涵tdd和pair works等等玩意  

                      

<完>

posted on 2005-01-08 20:53  蝈蝈  阅读(2732)  评论(9编辑  收藏  举报