《内核恐慌》19期读者反馈

本文是自己在听过《内核恐慌》第19期-《测试》后给两位主播写的一篇读者反馈,并在第20期的读者反馈环节中被两位主播提及,第一次在播客中听到自己写的内容还是挺激动的,内容涉及到自己对测试的一些理解,遂整理到博客中备忘,文中最后提到的视频也已经完成:【Kata】 Roman Numerals,推荐使用youtube观看,清晰度更高。

==========================以下为反馈信原文==========================

Hi 吴涛&Rio,

首先非常喜欢听你们的节目,我已经从头追了一遍,受益匪浅,也试着也反馈一次^^

作为一个已经被成功安利的TDD和Pair Programming“贱”行者(神志不清者^^),最近4年的代码几乎都是被测试驱动出来的(可见中毒之深),我想反馈一些我自己的体会。

我个人理解单元测试有两种作用:一个是保障作用,保障代码还是在按预期交付业务价值,这个这次就不提了^^;另一个就是驱动作用,也就是TDD中的中间那个Driven,大家谈论TDD的时候经常忽略的也就是这个Driven而关注在Test上。当Test起Driven作用的时候,一旦Driven的作用完成后也就是实现被Driven出来后理论上就可以被删除了。但写都写了,稍微修修剪剪就可以留着继续发挥余热,转化为可以起到保障作用的单元测试,何乐而不为。

那Driven的作用是如何被体现的呢?我们习惯的开发思路可以理解是从上到下(Top Down)开发模式,也就是碰到一个问题或需求,先做完备的设计再按之实现;而TDD所体现出的反而是一种自下而上(Bottom up)开发模式,简单说就是程序的设计和算法不再只是需要开始编码前就要想清楚所有细节(不代表不需要提前做设计,只是不像之前那么依赖一开始设计的正确性),而是可以基于对于目标的任务分解(Tasking)以及实现的逐步演进(TDD)并通过每次红绿Cycle后的重构的方式被驱动出来的,好处恰恰就是Rio所吐槽的那种“外包公司”所能达到的刚刚好满足需求的实现,不过我觉得在满足所有业务需求的前提下“刚刚好”不一定就是坏事,正好契合当今精益的思想,前提是有重构的保障,这种刚刚好的实现也是已经消除了识别出的BadSmell(例如代码重复,Switch,长方法等)后比较Clean的实现。而两种开发模式也没有好坏之分,只是思考的角度和方向的问题,可能最终的结果(实现)是一致的,就像找筷子的重心,从左边还是从右边无所谓,不过我们知道最快的方式是两个手指同时从两端逼近。这也是我的观点,什么东西都要尝试一下,只有真正用过之后才能客观的对比和选择(结果并不重要),也有可能双修和融合,在不同场景下发挥各自的擅长的能力,例如vim和emacs我就是双修的,也经常左右互搏^O^

文中提到了的TDD的三个原则。我想补充的是TDD真正实施的三个步骤,用我自己的理解就是:1.先写一个测试,让编译通过;2,只编写能恰好让所有测试通过的代码;3,重构,消除所有识别出的BadSmell。而本期节目中没有提到的重构(这也是人们在谈论TDD中经常忽略的),如果没有重构这个步骤的话,理论上确实所有的逻辑都可以通过无数的IF穷举输入与输出的映射来实现(也挺函数式^o^),我们都知道这样是不对的,代码将很快陷入腐化,我想这也是为什么节目中说可测试的代码都是啰嗦的代码的原因之一吧,总之我个人认为没有重构的TDD都是耍流氓。如果说前两步保证我们的代码实现了业务价值,那重构就保障了我们代码本身的质量和设计,从而避免代码的快速腐化,只有这样才能体现TDD的价值和好处。但一个重要的前提是测试要写对,否则很容易适得其反会严重影响重构以及变化(最简单的味道就是重构的时候需要修改测试),一种常见的问题就是测试Target不是业务价值(罗马数字与阿拉伯数字的转化结果是否正确)的是实现本身(例如测得是是否采用了XX算法处理罗马数字与阿拉伯数字的转化,这种情况下换一个算法就要修改测试),如果测试写的不对,则测试的稳定性以及价值会大打折扣,而写测试和维护测试的成本也会大大增加,这也正好说明了为什么大多数人不爱写测试吧,其实写好(对)测试确实也是挺难的,有的时候要比写好(对)实现还难很多。

而关于TDD很印度,将测试作为详细设计说明书的可运行版本,来实现分工和流程化。由于我们这儿没有严格的分工和分级,也没有架构师,设计师之类的角色,所以自己感受不到,我们只有BA,QA,Dev和UX这些角色,Dev自己(Pair)要负责一个Story的需求建议与反馈,任务拆分(Tasking),开发(TDD),前端,甚至给客户Showcase。所以这块我们还好,没有感觉到任何不适,反而在测试的保障(TDD的遗产)下我们可以灵活的修改我们的实现和设计,甚至灵活的响应需求的变化。我们现在项目的Dev人数在40多人,项目是.Net WebAPI + AngularJS(3年前就开始使用,现在尝试换到Reactjs)基于Micro-Service的,用的是吴涛最爱的C#,项目已经5年(从一开始就一直使用TDD的方式),目前还可以做到相对灵活的响应需求变化以及代码设计实现的演进,甚至工具框架的演进升级,可以说TDD也是功不可没的。

PS : 我在公司刚强烈推荐了代码恐慌,我一边开车听节目的时候一边偷笑,这群被“安了利洗了脑的家伙们”肯定听本期节目会产生各种不适^^,不过还好,我们这儿的人也都比较崇尚和而不同的环境,互通有无也没有什么不好,非常喜欢内核恐慌,希望有更多精彩的节目。

再PS:俗话说Talk is cheap,show me the money ^O^,我准备基于吴涛提到的那个罗马数字的Kata按我自己的理解做个TDD版本,争取再录个视频,也许更能表达我的想法,等做完(如果有那么一天^^)了再反馈给你们。

来自一个北京的忠实粉丝

2015-08-15 10:2437