论坛首页 综合技术论坛

TDD很痛苦

浏览 25190 次
锁定老帖子 主题:TDD很痛苦
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-08-31  
我们现在正在尝试TDD方式开发code,感觉TDD的测试真的是太痛苦了。
主要问题是准备数据,非常麻烦。

其实我只要测试一个方法,但是在此之前我需要做大量的准备工作才可以让我的测试开始工作。于是测试已经让我感觉眼花缭乱了。这个问题应该是unit test所共有的问题。但是如果做TDD,感觉会非常的扰乱自己的思路。

太纠结了。
review代码的时候,发现测试代码的混乱程度相当严重(虽然测试是用来给机器跑的,用来保证我们之后的重构)

难道这就是传说中的痛苦的敏捷过程?

不知道大家TDD的时候有没有这种感觉。
   发表时间:2010-08-31  
那请问你的思路原本是如何的呢?你实现的功能是如何设计,如何开发,又是如何验证的?如果说tdd会干扰你的设计思路,那是否因为你们具体实施的方式有问题?

方法的目标是为了减轻人工的劳动,如果感觉痛苦,应该立刻予以抛弃。

其实,我们现在实施的还不是tdd,只是利用unit test来对关键功能进行自动回归测试,这样比较适合我们目前的情况,至少是因为多种原因,造成不是每个功能点都能花费精力去准备测试用例的,所以也只能头疼医头,脚疼医脚,遇到问题,再用测试用例覆盖了。没感觉痛苦,即便有时人变懒了,很长时间没有补充unit test,遇到小功能的升级,看到几十个老的用例都可以pass,心里也是比较安定的。

BTW:我们很悲惨了,升级都没有专门的测试人员支持。开发人员的测试效果咱们就不多说了,有了单元测试以后,才感到有些许的安心啊。
0 请登录后投票
   发表时间:2010-08-31   最后修改:2010-08-31
blackchoc 写道
我们现在正在尝试TDD方式开发code,感觉TDD的测试真的是太痛苦了。
主要问题是准备数据,非常麻烦。

其实我只要测试一个方法,但是在此之前我需要做大量的准备工作才可以让我的测试开始工作。于是测试已经让我感觉眼花缭乱了。这个问题应该是unit test所共有的问题。但是如果做TDD,感觉会非常的扰乱自己的思路。

太纠结了。
review代码的时候,发现测试代码的混乱程度相当严重(虽然测试是用来给机器跑的,用来保证我们之后的重构)

难道这就是传说中的痛苦的敏捷过程?

不知道大家TDD的时候有没有这种感觉。


习惯了tdd开发方式的人无语的飘过

通常当某人抱怨测试不好写时,一般我的直觉就是,要测试的代码有问题

对代码质量的考核中,有一个重要指标,叫做可测试性

看你的描述,"做大量的准备工作才可以让我的测试开始工作",这是否意味着你这个类的过于复杂?
5 请登录后投票
   发表时间:2010-08-31   最后修改:2010-08-31
针对和数据库相关的方法,可以考虑使用DbUnit或者是基于内存的数据库技术来预置必要的数据。对于依赖上下文环境的方法,可以考虑使用Mock框架来预置一些对象。如果这两类方法都不能满足你所谓的“要准备很多数据”的话,那就不能100%的TDD了。单元测试覆盖率即使没有达到100%,能达到80%,也很不错了。

TDD,是很痛苦的,只要从项目一开始就坚持下去,对于此后的回归测试,看着一个个的Green bar,真的是很有成就感。

对于“基于内存的数据库技术”进行单元测试,可以参考JForum3.0的代码。还没有发布,可以通过SVN获得源代码。
0 请登录后投票
   发表时间:2010-08-31  
这个跟修炼正派武功一样的,速度慢,但是功力深. scrum就是邪派了,玩虚的. wwccss表跟我争,你敢不敢练TDD?
0 请登录后投票
   发表时间:2010-08-31  
做TDD其实并不痛苦。但学TDD真的是可能很痛苦。

学TDD最好的方法是和高手一起做Pair Programming。如果没有这个条件呢,那你也只能忍着痛苦,摸索着前进了。

以下有几点建议,希望能对你有所帮助。
1. 给自己多一点时间,比如说计划用一两年的时间掌握TDD,而不是一两个月。
2. 不要太强迫自己按照某种固定的套路来。如果某些Unit Testing太难做,就不要做了。
3. 如果觉得测试优先太痛苦,那就先写代码,后写测试。写好的测试,也是需要一个学习过程的。当你觉得对写测试有信心的时候,再试着改变次序,也未尝不可。
4. 学习TDD,关键其实是学习object oriented programming。因为TDD的关键不是为写出最牛B的测试代码,而是要写出最容易测试的代码。最容易测试的代码在绝大多数场合下和好的object oriented代码的标准是相一致的。
5. TDD不是Refactoring的必要条件。不要把Refactoring想得太神秘了,说白了,它不过是,把虽然能正常工作,但写得不好的代码改的更好一点而已。所以,觉得要做Refactoring的时候,一定做,不要管有没有测试代码。因为做Refactoring,是学习object oriented programming 的最好方法之一。
6. 做TDD Kata 很有乐趣,也很有帮助。http://codingdojo.org/ 点击KataCatalogue
7. 循序渐进,享受学习的过程。就象开车去一个地方,别总想着目的地,享受沿途的风景也很重要。
5 请登录后投票
   发表时间:2010-09-01  
引用
这个跟修炼正派武功一样的,速度慢,但是功力深. scrum就是邪派了,玩虚的. wwccss表跟我争,你敢不敢练TDD?


你这人一点都不光明磊落,讨论问题怎么不敢直接回帖,跑到这儿偷偷摸摸的发帖子,算什么?

scrum从来也没有说,不许做tdd。你不要将二者对立起来。要说到tdd,你敢把你的tdd代码拿出来吗?

tdd是很好的东西,但也不要将其作为解决一切问题的关键。这里面会太多的问题。比如团队的接受程度,比如测试代码的覆盖度,比如依赖环境的解决。比如测试数据的生成和维护。

强强,你不要老在这儿耍嘴皮子功夫,回去好好学习,研究研究技术。把这些问题都搞明白了,再来讨论。
0 请登录后投票
   发表时间:2010-09-01  
jinjiankang 写道
针对和数据库相关的方法,可以考虑使用DbUnit或者是基于内存的数据库技术来预置必要的数据。对于依赖上下文环境的方法,可以考虑使用Mock框架来预置一些对象。如果这两类方法都不能满足你所谓的“要准备很多数据”的话,那就不能100%的TDD了。单元测试覆盖率即使没有达到100%,能达到80%,也很不错了。

TDD,是很痛苦的,只要从项目一开始就坚持下去,对于此后的回归测试,看着一个个的Green bar,真的是很有成就感。

对于“基于内存的数据库技术”进行单元测试,可以参考JForum3.0的代码。还没有发布,可以通过SVN获得源代码。


我们的项目也是需要预先准备很多的数据来进行单元测试,而且还需要依赖数据库中大量的表中已经定义的数据,DbUnit听起来不错,有空了研究一下
0 请登录后投票
   发表时间:2010-09-01  
DBUnit给我们带来的问题是,它不能自动处理外键关系,表间关系复杂时,每次insert都会报错失败。请问有何解决方案?
0 请登录后投票
   发表时间:2010-09-01  
blackchoc 写道
我们现在正在尝试TDD方式开发code,感觉TDD的测试真的是太痛苦了。
主要问题是准备数据,非常麻烦。

其实我只要测试一个方法,但是在此之前我需要做大量的准备工作才可以让我的测试开始工作。于是测试已经让我感觉眼花缭乱了。这个问题应该是unit test所共有的问题。但是如果做TDD,感觉会非常的扰乱自己的思路。

太纠结了。
review代码的时候,发现测试代码的混乱程度相当严重(虽然测试是用来给机器跑的,用来保证我们之后的重构)

难道这就是传说中的痛苦的敏捷过程?

不知道大家TDD的时候有没有这种感觉。


看你要测试的代码属于那一块了,这里假设你是作的WEB应用

先考虑和数据库交互的部分

1)如果要测OR-Mapping,要准备的东西其实很少,一个对象本质上就是一句SQL。你一个个对象来,每个TestXXXDescript类其实只要准备一句SQL就能测了。
2)如果要测报表/DAO,需要准备的数据可能比较多。我的经验,对于一般复杂度的报表,也就十到二十个SQL。其实这个时候准备数据才是TDD的精髓。你要想清楚,怎么样用尽量少的数据,使你的Testcase有区分度。准备数据的过程也正是帮你理清思路的过程,并非像你说的“感觉会非常的扰乱自己的思路”。恰恰相反,TDD要求你准备完测试用例时已经对这个测试用例怎么实现有了比较清楚地想法,准备测试用例的过程就是一个帮助自己整理思路的过程
3)如果要测试复杂的报表或者存储过程,由于一个入口的逻辑非常多和复杂,并不是很符合“小,并可测”的要求。对于这种情况,一般把要测试的报表或存储过程看做黑盒子,对于每个check point写一个单独的用例。每个用例只测一个特性,所需的数据相对会较小,当然其绝对数量还是蛮多的。
一般和数据库交互的测试用例需要一个插入/删除数据的框架和工具,用的比较多的是DBunit。不过我们是自己写了一个框架,直接用SQL插入数据。两者没有本质区别

其次是Service部分
这部分通常使用Mock来测试,如果ServiceA依赖于ServiceB和DAO,而ServiceB依赖于ServiceC,在你测试ServiceA时要Mock出ServiceBMock和DAOMock,不用去管ServiceC。
如果一个Service依赖太多外界对象,你要Mock的东西太多,就要考虑重构了。


无论是SQL还是Mock,记住一点,你只要准备需要准备的数据。比如一张表上有50个字段,但你的实现只关注其中5个,那么就不要写其他45个字段。或者一个Service对外有5个依赖,但你的实现只关注其中2个,也只需要Mock这两个对象。这样的测试代码,结构才清楚,别人看了才知道你这个测试关注的是什么,想测的是什么。也才是有价值,可以维护的Testcase.
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics