TDD随想录

2014年我一直从事在敏捷实践咨询项目,这也是我颇有收获的一年,特别是咨询项目的每一点改变,不管是代码质量的提高,还是自组织团队的建设,都能让我们感到欣慰。涉及人的问题都是复杂问题,改变人,改变一个组织是个更复杂问题,这里可能涉及很多的非技术,非能力问题。

在2014年12月我在某企业内部推行TDD(测试驱动开发)培训,一共分4个课时完成一个特定需求的例子,看着大家一步一步的加深对TDD的理解,直到2014-12-31,也是2014的最后一天下午培训完TDD课程,经过一系列的总结过后,某参与人员说道:“单元测试需要写更多的代码,但是从项目的总体来看,一个字‘值’.”。紧接着后来某参与人员发了一份其关于TDD培训感受,名叫《TDD随想录》也将是本文的主题,本文或许更好的说是转载此文,了解一个开发人员对TDD了解的心路历程,以及对TDD的看法。

注:原文发布与hxfirefox的https://github.com/hxfirefox/blog/blob/master/TDD/TDD%E9%9A%8F%E6%83%B3%E5%BD%95.md.

原文如下:

TDD随想录

谨以本文献给TDD的开创者与传播者

本文纯属个人经历,如有雷同纯属巧合

我从不觉得自己是一个好的程序员,甚至可能连合格都谈不上,不过在内心深处我却渴望着在编程这件事上获得成功。

可惜每次审视自己写的暂且称之为代码的东西,都会有挫折感,想重构却又感觉盘根错节,难以下手;想重写却又感觉自己好不容易写出来的,也花了不少心思,就这样丢弃心有不甘。

也曾思考过如何才能写好代码,有段时间觉得只有严格符合编程规范的代码才是好代码进而如同遵守戒律一样地字字斟酌,还有段时间觉得只有用上设计模式才能称之优秀代码进而非模式不用,一切套用模式。不过这些都没有让我走出开发的迷雾,永远是加不完的班,修不完的bug。

究竟是否有一种方法能够让我拨开开发迷雾,至少能够让我能够轻松地修剪代码,降低bug发生率,那么我觉得这种方法在我身上就是成功的。

初次接触到TDD是通过公司内部的“代码大全培训”,犹如十月革命中阿芙勒尔号的一声炮响,为我打开了软件开发的视野。先测试后开发,小步迭代,持续集成,这些新名词突然涌进了我的大脑,既新鲜又晦涩。犹如人的幼年容易犯幼稚病一样,初识这些新名词就以为了解了TDD的一切,结果却发现在实践过程中处处碰壁,举步维艰。对TDD中每个环节真正隐含的开发思想的囫囵吞枣,让这一次的培训只在我脑中留下TDD的一个模糊身影:为软件开发结下一张安全网。

虽然未领悟精髓,但培训后体验和直觉告诉我TDD是一条通往我向往的软件成功的道路,尽管自己摸索前行比较坎坷。很幸运的是团队获得了随队敏捷教练的支持,结对让我系统地了解到了TDD的思想。

测试先行,其实讲的是需求边界,测试不是漫无目的而是精确计算成本的一项活动。测试从何而来,从需求来,需求推演出测试,也规划出产品边界,不能反映需求的测试是一种浪费,因此引申出开发需要讲求适当。开发是一项功利性的活动,永远都在追求盈利,而测试就一条红线,一旦跨过就意味着亏损。

小步迭代,“让子弹飞”中有句话很经典:步子要一步一步迈,一步迈大了,咔,容易扯着蛋。代码堆叠的后遗症是复杂,复杂到没人愿意触碰,且不停地咒骂这代码有多烂,这是步子迈太大的真实写照。TDD讲求的小步迭代是写完一个测试再去写完一个实现,每个实现都是通过测试的,如此累加小胜为大胜,最后所有代码的收尾也不过是让最后一个测试通过而已,就是这样简单。

重构,这是我最喜欢的部分,为啥?因为这里面所有的活动都会要求你去思考,且看上去都像是让你的代码向着大师级代码前进。漂亮的代码并不是堆砌各种技巧,而是在正确的时间,正确的地点做正确的事,重构很容易实现这个目标。重构是一件让人一旦开始就会欲罢不能的事,会让开发者在整个开发阶段都能够不停地去思考、实践再思考,直到无法再添加或删除一个字母。

持续集成,你终究是需要交付产品的,产品就是客户需要的价值,就如同厨师终究会端出客人点的大餐一样,没有哪个厨师是把所有食材罗列着呈现给你的,而是混合在一起,蒸煮炖烧,有些食材需要先处理,这样吃起来才软硬适中,而有些则是最后下锅,这样吃起来才鲜嫩多汁,厨师就是这样一步步将食材集成起来,每一步的处理都是可用都是有价值的,都是为后续进行的铺垫。软件开发也一样,持续集成就要保证每一次的完成都是有价值都可以为后续提供支撑。

写到这里也许会有人问你如何知道TDD是真理,是康庄大道,它一定适合每个人吗?不,我并不知道,我所写的一切只是发生在我身上的一段经历。这段经历告诉我TDD迫使我去更多的思考,去切割我那些冗长且复杂又不切实际的胡思乱想,把它们碾碎成一个个小片段,提炼,过滤,不断累加,最终变成最接近交代价值的东西,而这最终的东西正是我一直在追求的那个成就感。如果想要知道TDD是不是适合自己,最好的办法就是去尝试,去亲身体验一下,无论好坏也许你能获得比我更多的体会。

博主总结

TDD并不是万能的,但是TDD也不是一无是处的,重要的是用方法论的人,引入某同事一句话:

站在教学的角度来讲,我还是很推崇TDD的,TDD是一个很好的思维框架,如果非要教人一个思维框架的话就得教TDD,
不然人会瞎碰,不思考,不总结,不结果导向,靠灵感编程,凭直觉设计,撞大运修bug。最糟糕的是因为没有好的习惯
会接二连三的发生灵异现象。同一道题,习惯不好的人做,总能做出无数种新问题来。而且问题套问题,给他解决要浪费
我半天时间,如果他学会了TDD出的错只在最近一个引入的变化里,就好纠正多了。甚至他自己都能纠正。

博主很是赞同该同事的看法,并且作者认为:

tdd重要的不是测试代码本身,是解决问题的思维,也许可以泛化,哪怕没测试,如果能够做到快速验证,反馈,价值的
稳定叠加,有足够信心,也未尝不可。也许你会说测试可以cover功能,那么如果只有这一点的话,我更喜欢BDD
(behavior-driven development),因为这具有用户最终的使用价值。如果你说快速定位bug,我们我更倾向于BDD
(bug-driven development,自创的)。这写都是TDD的结果导致的好处所在,而价值反馈思维才是实现TDD背后原理。
TDD驱使我们以结果导向,使得我们简单设计(并不是无设计),日常重构我们的代码库,注重交付价值流稳定叠加。

不管是《TDD随想录》或者某大牛的《TDD并不是看上去的那么美》,告诉我们世上并没有放之四海皆准的法则,TDD好坏在于你的判断,本文并不会给你一个完美的答案,这需要你自己的发掘。

时间: 2024-10-18 17:13:04

TDD随想录的相关文章

TDD(测试驱动开发)培训录

2014年我一直从事在敏捷实践咨询项目,这也是我颇有收获的一年,特别是咨询项目的每一点改变,不管是代码质量的提高,还是自组织团队的建设,都能让我们感到欣慰.涉及人的问题都是复杂问题,改变人,改变一个组织是个更复杂问题,这里可能涉及很多的非技术,非能力问题. 在2014年12月我在某企业内部推行TDD(测试驱动开发)培训,一共分4个课时完成一个特定需求的例子,看着大家一步一步的加深对TDD的理解,直到2014-12-31,也是2014的最后一天下午培训完TDD课程,经过一系列的总结过后,某参与人员

随想录(移动app下的生活)

[ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 我算不上很潮的人,使用移动app的时间也非常短.换成android手机也是最近一年的事情,但是它对我生活的影响还是蛮大的.这两个星期,我利用年假出去旅游了一番,收获还是很大的.从上海到北京.天津,又从北京到成都,又从成都回来,兜了这么一大圈,应该也有10000多里路吧,也算是蛮能折腾的.中间除了参观中关村.空港开发区.成都天府软件园,还去了很多名胜,而这所有的一切基本上一个手机就可以搞定了.

TDD测试驱动开发

TDD测试驱动开发 一.概念 TDD故名思意就是用测试的方法驱动开发,简单说就是先写测试代码,再写开发代码.传统的方式是先写代码,再测试,它的开发方式与之正好相反. TDD是极限编程的一个最重要的设计工具之一,使得我们编码的目的更加明确.而极限编程的另一个最重要的工具—重构.重构改变的是代码的内部结构,而不会改变外部接口功能.一整套完备的测试用例可以保证我们的程序更加健壮,功能更加完善. 二.作用 站在用户使用的角度去思考如何完成产品设计,强迫开发人员事先思考完善的测试用例并提供不考虑细节的外部

我看TDD测试驱动开发

今天在实验室给大家介绍了一下TDD和Docker,大家对TDD都比较感兴趣,包括老板,也问了一些问题. 还是从头来说TDD吧,TDD作为敏捷开发领域的领头军,充满魅力,同时也充满争议.一切从三大军规说起: 除非这能让失败的单元测试通过,否则不允许去编写任何的产品代码. 只允许编写刚好能够导致失败的单元测试. (编译失败也属于一种失败) 只允许编写刚好能够导致一个失败的单元测试通过的产品代码. 上面这三个是网上找的中文翻译,回来后,我还是决定要把英文原文找出来,相对与上面三句拗口蹩脚的翻译,我相信

TDD学习笔记【四】--- 如何隔离相依性 - 基本的可测试性

前言 相信许多读者都听过「可测试性」,甚至被它搞的要死要活的,还觉得根本是莫名其妙,徒劳无功.今天这篇文章,主要要讲的是对象的相依性,以及对象之间直接相依,会带来什么问题.为了避免发生因相依性而导致设计与测试上的问题,本文会清楚地说明该如何隔绝对象的相依性.最后会说明如何通过简单的 stub 对象来进行测试,而不必相依于production code 中执行时所实际相依的对象.补充的部分,更是我觉得测试所能带来的庞大优点,怎么验证对象设计的好坏,让测试告诉你. 什么是相依性 假设现在有一个 Va

TDD学习笔记【三】---是否需针对非public方法进行测试?

前言 在Visual Studio 2012 中,针对Unit Test 的部分,有一个重要的变动: 原本针对「测试对象非public 的部分」,开发人员可通过Visual Studio 2010 自动产生的accessor ??来进行测试.但在Visual Studio 2012 中,将此功能移除了. Accessor ??其背后的原理,是将对象通过很「脏」的反射方式,把对象内所有的东西public 出来.并且Visual Studio 在更新对象后,进行与设计测试时,会帮你做同步产生acce

TDD学习笔记【二】---单元测试简介

大纲 Testing 的第一个切入点:单元测试. 本篇文章将针对单元测试进行简介,主要内容包含了5W: Why What Where Who When 而How 的部分,属于实现部分,将于下一篇文章介绍工具与简单的范例. 最后会提到测试用例所代表的意义与其重要性. 前言 单元测试,是开发人员最该写的测试程序,却也是最容易被忽略的测试. 大家常碰到的测试相关问题是: 往往一堆人写测试程序时,自以为是在写单元测试,却压根就不是单元测试,而是集成测试. 生产代码是我写的,如果测试程序也是我写,那有什么

python+selenium自动化软件测试(第10章):测试驱动TDD

测试驱动开发模式,要求开发在写业务代码的时候,先写出测试代码,同时单元测试例子决定了如何来写产品的代码,并且不断的成功的执行编写的所有的单元测试例子,不断的完善单元测试例子进而完善产品代码, 这样随着功能的开发完成,测试代码也会对应的完成, 很显然,这是一个全新的开发模式, 在一定程度上,可以完全的提高软件的质量,以及开发可以对自己写的代码进行一个全面的评估和测试. TDD 模式是一个很大的概念,在这里, 我重点介绍下测试驱动模式与自动化的融合以及精简自动化的测试代码.下面我们来看一个登录的案例

ASP.NET MVC 随想录—— 使用ASP.NET Identity实现基于声明的授权,高级篇

在这篇文章中,我将继续ASP.NET Identity 之旅,这也是ASP.NET Identity 三部曲的最后一篇.在本文中,将为大家介绍ASP.NET Identity 的高级功能,它支持声明式并且还可以灵活的与ASP.NET MVC 授权结合使用,同时,它还支持使用第三方来实现身份验证. 关于ASP.NET Identity 的基础知识,请参考如下文章: ASP.NET MVC 随想录——开始使用ASP.NET Identity,初级篇 ASP.NET MVC 随想录——探索ASP.NE