这两天在看关于单元测试方面的东西,xcode 5也直接集成了XCTest,过去Logic Tests和Application Tests的概念也没有了,现在统一默认都是Application Tests,也尝试了一下用TDD来写一个类,感觉有点别扭,难道是我的使用方法不对,大家在实际开发中TDD应用的多么。
附blog一枚:
http://iosunittesting.com/
我的感受是严格的TDD是必须和结对编程配合起来的,然而这种开发方式的选择性非常强,和臭豆腐一样的特点,爱的人爱死,恨的人恨死,比如如果强制要我去结对编程,我宁可先辞职再去找工作,或者找不到工作的话单干算了。
另一方面,TDD要和写程序应该写单元测试分开,好的项目,好的程序员都是应该严格认真的写单元测试的,而且对测试代码的重视程度应该等同功能代码。不过单元测试一定要有完整的持续构建和版本控制系统来配合,否则也白白浪费了写单元测试的价值。
我不喜欢的是TDD中间那个D,但是坚持编程必须带着测试,也就是说Develop With Tests (DWT)是必须的,TDD是实现DWT的一种具体实践方式,但不应该是唯一的方式,也不应该是被强迫采用的方式。
十月份团队转移开始整Html5依赖一直写javascript 过程很痛苦 js这门早就应该滚出编程界的语言来说 我觉得TDD是很需要的 至少你的语言扩展和工具相关全部都要tdd 一来要tdd可以让你写下一个函数之前确定需要兼容的浏览器 可以实时的跑出多个浏览器的结果 二来这门语言的混乱程度 在你重构的时候还是很需要参考下之前的测试用例的 改错的几率比较大 而针对传统的javaweb或者android来说 tdd则在团队里不是必须的 很多都是后补的用例 但是毋庸置疑 如果你觉得应该TDD那么请丢下顾虑彻底的TDD 带来的美妙程度是你之前无所想象的 所以我决定以后再回java也坚决的可以TDD就TDD
像楼上 coredump 说的,TDD 中间那个 D 简直就是反人类的存在。很同意一点是我们其实要做的是 DWT。从我们实施 TDD 的结果来看,切身体会是 1. 开发周期明显拉长。 2. 代码质量没有太大幅度的提高。 3. 很多严格 TDD 出来的代码块依旧需要大量重构。
聊天的时候发现好童鞋都是这样认为的:写 unit test 就是 TDD …… 然后我就不知道怎么说下去了。
tests 存在的意义不只是开发过程中的爽心爽肺,最大的意义在于,代码交接和重构的时候。(我是不是说多了 ……)
我们现在做到了 UE 交互行为都是有 tests 验证的。 关于 UE 怎么做 test 最重要的一点就是:不要用全局变量 …… 没有不可测试的语言,只有不可测试的代码。
12楼 @coredump 首先,对于开发人员来说,版本控制是必须的,而不是团队规模决定的,有一定开发经验的人都会认识到这一点;其次,持续构建也是各软件项目必经之路,没有哪个项目是一蹴而就的,如果没有TDD,在bug fix时引入新bug是完全可能的。当然,TDD不是万能的,只有在测试代码覆盖达到一定量的情况下,才可能做到持续构建的健壮性。通常个人开发的项目规模较小,甚至很多项目可能都是在脑袋中想出来的,都不一定有规划文档、需求管理和开发计划的东西,如果加入测试代码就显得有些随心所欲——至少在我看来,个人开发的项目中对自己进行严格的过程管理和活动限制是非常难的。所以说,在个人项目中由于测试代码的质量和数量的不足,很难能展现TDD的优势。 举个简单的例子:我第一次做TDD是在一个python的项目中。我们都知道,python这种语言最大的问题就在于“如果你的测试不能覆盖100%的代码,那么你可能因为一个字母的大小写错误导致很严重的bug”。在那一次的项目中,我们的测试代码数量超过了实现代码的数量,基本做到了95%以上的测试覆盖,在项目收尾阶段,测试组反馈的bug数远小于以往的项目,在结项交付产品后,从未收到因代码bug导致的客户反馈。
10楼 @nickdine 可以保证保证重构可靠的不是 TDD,而是 Unit Test …… 而且严格的 TDD 关键在于中间那个 D。 能保证重构安全性的是测试本身,而不是测试是怎么来的。测试先写还是测试后写,都无所谓。TDD 强调的是测试先行。 换句话说,只要有足够的测试,测试覆盖率足够高,那你重构就相对安全。
我前面所说的通过严格 TDD 出来的代码需要重构,意思是说,测试先行在真正写复杂业务逻辑的时候其实并不那么高效。遵循严格 TDD 出来的代码很多时候是不能满足需求的,不得不重新再写一遍。而且有时候你的 tests 也不得不跟着一起改。
9楼 @akunamotata 测试先行是一个很好的想法,通过测试来构建代码,这也是 TDD 的精髓。
但是问题是,如果你只是做一个巨大项目中的一层。你要做的是验证上层过来的数据,处理这些数据,调用下层的接口,这三件事的时候,你的 TDD,怎么个 Driven 是很有难度的。感觉就是一件很顺的事情非要扭过来逆着来做一样。
我们有严格按照 TDD 来做过,做一些 example 的时候感觉简直碉堡了,但是做到真正项目里来的时候,就觉得被束缚住手脚。不如我先写一部分业务代码,然后再对这些业务代码加上白盒的单元测试。
17楼 @liyinkan 我觉得没有冲突啊,就像你说的做中间一层,验证上层过来的数据,你可以先Mock数据,然后写验证的测试用例。所有一切外部的数据和接口都可以Mock,你说没有上层数据和调用下层的接口就没办法TDD,这和没有上层数据和调用下层的接口就没办法写验证处理逻辑是一个道理。
18楼 @akunamotata 嗯,很赞同。只是“测试先行”做起来就很难受。所以现在我们提倡的是,就先写业务逻辑吧,然后再写test,这样感觉也挺好。
19楼 @liyinkan 第一,因为前期要花大量时间在TDD上,心理上特别不值。第二,如果团队不能坚持,前面的test都白写。
不测试先行,一般项目风险比想象的要大很多,但是用了之后,如果碰上大量逻辑修改,TDD又会成为你的噩梦,是挺纠结的。
16楼 @liyinkan 你说的没错。如果是做产品,TDD是个很不错的东西,做项目就不好说了。严格说来,只要习惯了TDD的做法,你会发现最终的交付质量和开发周期都会远好于预期。但是国内的老板们很少有知道TDD的好处,或是只是理论上支持但实际过程中又等不及看到阶段目标。通常,TDD中的单元测试代码的编写时间是少于不写单元测试代码项目的测试时间的,而国内的很多项目甚至没有规划足够的测试时间,更不要说先写单元测试代码了。非TDD的单元测试代码和TDD是不同的,TDD要求先写单元测试代码,在写测试代码的过程中既需要你对需求的进一步了解,同样也可以在编写代码的过程中发现架构设计的合理性。而非TDD的单元测试代码很大程度受限于你的实现,很少见人这么写单元测试时不是就和着现有实现的。
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/
没用过,~~ 我居然没听过,真够菜的了。。
名词我不懂,我都是单独建demo工程写模块,测试好之后在整合到项目里。然后那些单独建立的demo工程都留着,以后写程序还能用到。
组织结构/业务等等不能写成通用模块的代码就没办法了。。
TDD的一般来说是这么来的,几个大牛聚在一起搞个项目,然后有人说,要不我们来搞个TDD吧,另外几个说,可以啊,然后就搞了,之后有人发现,妈呀,他们的项目的质量怎么这么高啊,嗯,TDD真是好东西啊。我们全公司推广一下吧,去找人先给大家讲讲怎么搞吧。于是乎这个世界让又多出了一个敏捷教练的职位。
所以,你们都真心想太多了。
正经点说:
几乎所有的技能型工作,根据其掌握程序,大致可以划分为5类人:新手,高级新手,胜任者,精通者,专家。TDD的使用有一个前提(来自于TDD的提出者),就是技能水平应该在精通者,专家这个级别。而这两个级别的人加起来一般来说不足20%。所以大部分人用不用TDD结果没差别。(来源:《程序员的思维训练》一书)