大家在开发中使用TDD么?

walkingway 发布于 2014年01月05日
tinyfool 等1人欣赏。

这两天在看关于单元测试方面的东西,xcode 5也直接集成了XCTest,过去Logic Tests和Application Tests的概念也没有了,现在统一默认都是Application Tests,也尝试了一下用TDD来写一个类,感觉有点别扭,难道是我的使用方法不对,大家在实际开发中TDD应用的多么。

附blog一枚:

http://iosunittesting.com/

共30条回复
tinyfool 回复于 2014年01月05日

我们其实没怎么用过,应该用用

terryso 回复于 2014年01月05日

严格tdd暂时是没有做到,不过一些重要模块还是有做单元测试的

newyo 回复于 2014年01月06日

这不都是和写准确足够的注释一样都是大家都知道要这么做,大家都希望别人会这么做,但是没有人会这么做的事情吗。

coredump 回复于 2014年01月06日

我的感受是严格的TDD是必须和结对编程配合起来的,然而这种开发方式的选择性非常强,和臭豆腐一样的特点,爱的人爱死,恨的人恨死,比如如果强制要我去结对编程,我宁可先辞职再去找工作,或者找不到工作的话单干算了。

另一方面,TDD要和写程序应该写单元测试分开,好的项目,好的程序员都是应该严格认真的写单元测试的,而且对测试代码的重视程度应该等同功能代码。不过单元测试一定要有完整的持续构建和版本控制系统来配合,否则也白白浪费了写单元测试的价值。

我不喜欢的是TDD中间那个D,但是坚持编程必须带着测试,也就是说Develop With Tests (DWT)是必须的,TDD是实现DWT的一种具体实践方式,但不应该是唯一的方式,也不应该是被强迫采用的方式。

nickdine 回复于 2014年01月06日

十月份团队转移开始整Html5依赖一直写javascript 过程很痛苦 js这门早就应该滚出编程界的语言来说 我觉得TDD是很需要的 至少你的语言扩展和工具相关全部都要tdd 一来要tdd可以让你写下一个函数之前确定需要兼容的浏览器 可以实时的跑出多个浏览器的结果 二来这门语言的混乱程度 在你重构的时候还是很需要参考下之前的测试用例的 改错的几率比较大 而针对传统的javaweb或者android来说 tdd则在团队里不是必须的 很多都是后补的用例 但是毋庸置疑 如果你觉得应该TDD那么请丢下顾虑彻底的TDD 带来的美妙程度是你之前无所想象的 所以我决定以后再回java也坚决的可以TDD就TDD

tinyfool 回复于 2014年01月06日

其实可能比较复杂的一个问题是iOS这样的UI/UE为主的编程,很难TDD吧?

liyinkan 回复于 2014年01月06日

像楼上 coredump 说的,TDD 中间那个 D 简直就是反人类的存在。很同意一点是我们其实要做的是 DWT。从我们实施 TDD 的结果来看,切身体会是 1. 开发周期明显拉长。 2. 代码质量没有太大幅度的提高。 3. 很多严格 TDD 出来的代码块依旧需要大量重构。

聊天的时候发现好童鞋都是这样认为的:写 unit test 就是 TDD …… 然后我就不知道怎么说下去了。

tests 存在的意义不只是开发过程中的爽心爽肺,最大的意义在于,代码交接和重构的时候。(我是不是说多了 ……)

我们现在做到了 UE 交互行为都是有 tests 验证的。 关于 UE 怎么做 test 最重要的一点就是:不要用全局变量 …… 没有不可测试的语言,只有不可测试的代码。

akunamotata 回复于 2014年01月06日

个人感觉TDD对个人开发帮助并不大,主要贡献在于团队,在团队中发挥稳定与保障的作用。

akunamotata 回复于 2014年01月06日

7楼 @liyinkan 我说的也是这个意思,其实TDD对个人也是有帮助的,帮助你理解与思考功能逻辑关系。

nickdine 回复于 2014年01月06日

7楼 @liyinkan TDD不是说能多么的提高质量 而是说为了后续的重构加一个保障 并不能避免重构 应该是在后续不断的重构中提高质量 如果不重构TDD鸟用没有

coredump 回复于 2014年01月06日

6楼 @tinyfool 我不这么认为,在现在工作之前,我是Qt项目的全职开发者 (Brisbane QML team), 要说做UI,Qt基本上全部都是GUI, QML就更不用说了,不过这丝毫不影响unit test的编写。

coredump 回复于 2014年01月06日

10楼 @nickdine 所以我说了如果TDD,那么最好结合结对编程,如果写了tests,那么一定要有健壮的持续构建和版本控制配合,否则就是白费力气。

tinyfool 回复于 2014年01月06日

11楼 @coredump 我主要是不会啊,我不知道怎么搞啊……

玉楼 回复于 2014年01月06日

12楼 @coredump 首先,对于开发人员来说,版本控制是必须的,而不是团队规模决定的,有一定开发经验的人都会认识到这一点;其次,持续构建也是各软件项目必经之路,没有哪个项目是一蹴而就的,如果没有TDD,在bug fix时引入新bug是完全可能的。当然,TDD不是万能的,只有在测试代码覆盖达到一定量的情况下,才可能做到持续构建的健壮性。通常个人开发的项目规模较小,甚至很多项目可能都是在脑袋中想出来的,都不一定有规划文档、需求管理和开发计划的东西,如果加入测试代码就显得有些随心所欲——至少在我看来,个人开发的项目中对自己进行严格的过程管理和活动限制是非常难的。所以说,在个人项目中由于测试代码的质量和数量的不足,很难能展现TDD的优势。 举个简单的例子:我第一次做TDD是在一个python的项目中。我们都知道,python这种语言最大的问题就在于“如果你的测试不能覆盖100%的代码,那么你可能因为一个字母的大小写错误导致很严重的bug”。在那一次的项目中,我们的测试代码数量超过了实现代码的数量,基本做到了95%以上的测试覆盖,在项目收尾阶段,测试组反馈的bug数远小于以往的项目,在结项交付产品后,从未收到因代码bug导致的客户反馈。

tinyfool 回复于 2014年01月06日

12楼 @coredump 我也是觉得奇怪,我感觉TDD跟结对毫无关系啊

liyinkan 回复于 2014年01月06日

10楼 @nickdine 可以保证保证重构可靠的不是 TDD,而是 Unit Test …… 而且严格的 TDD 关键在于中间那个 D。 能保证重构安全性的是测试本身,而不是测试是怎么来的。测试先写还是测试后写,都无所谓。TDD 强调的是测试先行。 换句话说,只要有足够的测试,测试覆盖率足够高,那你重构就相对安全。

我前面所说的通过严格 TDD 出来的代码需要重构,意思是说,测试先行在真正写复杂业务逻辑的时候其实并不那么高效。遵循严格 TDD 出来的代码很多时候是不能满足需求的,不得不重新再写一遍。而且有时候你的 tests 也不得不跟着一起改。

liyinkan 回复于 2014年01月06日

9楼 @akunamotata 测试先行是一个很好的想法,通过测试来构建代码,这也是 TDD 的精髓。

但是问题是,如果你只是做一个巨大项目中的一层。你要做的是验证上层过来的数据,处理这些数据,调用下层的接口,这三件事的时候,你的 TDD,怎么个 Driven 是很有难度的。感觉就是一件很顺的事情非要扭过来逆着来做一样。

我们有严格按照 TDD 来做过,做一些 example 的时候感觉简直碉堡了,但是做到真正项目里来的时候,就觉得被束缚住手脚。不如我先写一部分业务代码,然后再对这些业务代码加上白盒的单元测试。

akunamotata 回复于 2014年01月06日

17楼 @liyinkan 我觉得没有冲突啊,就像你说的做中间一层,验证上层过来的数据,你可以先Mock数据,然后写验证的测试用例。所有一切外部的数据和接口都可以Mock,你说没有上层数据和调用下层的接口就没办法TDD,这和没有上层数据和调用下层的接口就没办法写验证处理逻辑是一个道理。

liyinkan 回复于 2014年01月06日

18楼 @akunamotata 嗯,很赞同。只是“测试先行”做起来就很难受。所以现在我们提倡的是,就先写业务逻辑吧,然后再写test,这样感觉也挺好。

akunamotata 回复于 2014年01月06日

19楼 @liyinkan 第一,因为前期要花大量时间在TDD上,心理上特别不值。第二,如果团队不能坚持,前面的test都白写。

不测试先行,一般项目风险比想象的要大很多,但是用了之后,如果碰上大量逻辑修改,TDD又会成为你的噩梦,是挺纠结的。

liyinkan 回复于 2014年01月06日

20楼 @akunamotata 我们还遇到过,改了个东西然后某个测试 fail,过几天就发现这个测试被删除了。这是真实的故事 ……

akunamotata 回复于 2014年01月06日

21楼 @liyinkan 理解,我也这么干的,特别是要上线的时候,一直测试不通过,这个通过了那个又不能过了,最后就忽略测试,直接编译打包......

玉楼 回复于 2014年01月06日

16楼 @liyinkan 你说的没错。如果是做产品,TDD是个很不错的东西,做项目就不好说了。严格说来,只要习惯了TDD的做法,你会发现最终的交付质量和开发周期都会远好于预期。但是国内的老板们很少有知道TDD的好处,或是只是理论上支持但实际过程中又等不及看到阶段目标。通常,TDD中的单元测试代码的编写时间是少于不写单元测试代码项目的测试时间的,而国内的很多项目甚至没有规划足够的测试时间,更不要说先写单元测试代码了。非TDD的单元测试代码和TDD是不同的,TDD要求先写单元测试代码,在写测试代码的过程中既需要你对需求的进一步了解,同样也可以在编写代码的过程中发现架构设计的合理性。而非TDD的单元测试代码很大程度受限于你的实现,很少见人这么写单元测试时不是就和着现有实现的。

coredump 回复于 2014年01月06日

15楼 @tinyfool TDD和结对的关系是这样的: 一般经典的TDD开发情景下,结对编程的2个人,一个稍侧重测试,一个稍侧重实现,两个人一起迭代边讨论边开发。 A: 我觉得这个API用起来用该这样 (写了几行测试码)B:我弄个简单实现,跑跑看测试是不是想要的效果....

因为结对编程时有两个脑袋,需要沟通,在一个脑袋想一个东西如何实现和另一个脑袋想如何用的时候,TDD可以作为两个脑袋进行沟通的代码语言。

如果不用结对的话,TDD用起来就像是一个得了精神分裂的疯子,否则实在没必要在自己脑袋既清楚如何实现又清楚如何用的时候用测试来假装驱动自己的脑袋。一个脑袋的正常逻辑顺序时这样的:1. 我觉得这个东西应该这样弄(实现出来) 2. 写点代码验证一下(单元测试)

而对与整个项目来说,代码有没有测试是显性的,是劳动的可见输出;先有代码还是先有测试,是隐形的,是劳动过程的不同风格。 项目对成员的劳动应该是用结果来衡量,那就是:你的代码必须和测试同时进入代码库,并通过CI的检测。 而对你生产的过程,项目成员应该选用最适合自己,生产效率最高的那种。

延伸阅读: http://maxheapsize.com/2009/09/13/how-pair-programming-can-help-you-to-get-into-test-driven-development/

liyinkan 回复于 2014年01月07日

24楼 @coredump 精神分裂的疯子 说的太对了 ……

freecunix 回复于 2014年01月07日

没用过,~~ 我居然没听过,真够菜的了。。

名词我不懂,我都是单独建demo工程写模块,测试好之后在整合到项目里。然后那些单独建立的demo工程都留着,以后写程序还能用到。

组织结构/业务等等不能写成通用模块的代码就没办法了。。

董一凡 回复于 2014年01月07日

TDD的一般来说是这么来的,几个大牛聚在一起搞个项目,然后有人说,要不我们来搞个TDD吧,另外几个说,可以啊,然后就搞了,之后有人发现,妈呀,他们的项目的质量怎么这么高啊,嗯,TDD真是好东西啊。我们全公司推广一下吧,去找人先给大家讲讲怎么搞吧。于是乎这个世界让又多出了一个敏捷教练的职位。

所以,你们都真心想太多了。

正经点说:
几乎所有的技能型工作,根据其掌握程序,大致可以划分为5类人:新手,高级新手,胜任者,精通者,专家。TDD的使用有一个前提(来自于TDD的提出者),就是技能水平应该在精通者,专家这个级别。而这两个级别的人加起来一般来说不足20%。所以大部分人用不用TDD结果没差别。(来源:《程序员的思维训练》一书)

coredump 回复于 2014年01月07日

27楼 @董一凡 “所以大部分人用不用TDD结果没差别。” 这句话是不对的,很显然对大部分人来说按照经典TDD流程,会起到非常明显的负面效果。

freecunix 回复于 2014年01月07日

28楼 @coredump ~~ 😓

nickel 回复于 2014年01月07日

我支持27楼 @董一凡 的说法

关键是别为TDD而TDD。如果你的模块逻辑比较复杂,而且希望在给其他模块调用前确保这个包括每个接口的流程正确,难道你不需要为其提供一组单元测试吗?这算不算TDD?我不知道算不算,反正我只是觉得这是必须要做的事而不是因为追求某个模式。

本帖有30个回复,因为您没有注册或者登录本站,所以,只能看到本帖的10条回复。如果想看到全部回复,请注册或者登录本站。

登录 或者 注册
相关帖子

[顶 楼]
|
|
[底 楼]
|
|
[首 页]