《敏捷无敌》

下载本书

添加书签

敏捷无敌- 第23部分


按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
模锹伎⒐讨凶钚麓锍傻慕崧邸6艺飧龌贡匦敫鶳roduct Backlog对应起来。概要设计是确保大家在XP的过程中不会脱离轨道,不会天马行空。”
  “嗯,那我们就先按照这个思路实行一段时间。可以通过每次的Sprint回顾会议进行调整。那我们再来看看TDD编程?”阿捷把头转向大民。
  “好!从它的英文Test…Driven Development即可以看出是测试驱动的。也就是说是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。这一点跟我们大多数人日常的实践是不同的。我们虽然也有UT,并且数量也很多,但这些UT用例基本都是在编写完功能代码之后,才编写的。”
  “我觉得区别不大啊!最终都是为了验证功能的正确性。”小宝说道。
  “不一样!事后的单元测试较TDD会失去大半的意义。我们先来看看通用的测试驱动开发基本过程。”大民边说边把每一步列在白板上。
  (1)明确当前要完成的功能。可以记录成一个 TODO 列表。
  (2)快速完成针对一个功能的测试用例编写。
  (3)测试代码编译通过,但测试用例通不过。
  (4)编写对应的功能代码。
  (5)测试通过。
  (6)对代码进行重构,并保证测试通过。
  (7)循环完成所有功能的开发。
  大民转过头来,指着刚刚写完的7条说,“乍一看,似乎也没什么。但深奥之处就在于第一步的明确上。如何明确?通常由业务分析人员、测试人员、开发人员进行一次讨论,就要完成的功能的验收条件达成一致并形成记录,然后测试人员设计并编写验收测试用例,开发人员编写单元测试和并实现功能代码。这样,测试人员早期介入,从而可以避免开发人员与测试人员理解不一致,开始产生争执并阻塞等待业务分析人员或者行政主管的仲裁。”
  “嗯,测试就是应该越早介入越好!是吧,阿紫?”阿朱征求阿紫的支持,阿紫很快点头回应。
  “对于开发人员来讲,可以强迫他从测试的角度来考虑设计,考虑代码,这样才能写出适合于测试的代码。”大民接着讲。
  “从另外的一个角度上说,坚持测试优先的实践,可以让开发人员从一个外部接口和客户端的角度来考虑问题,这样可以保证软件系统各个模块之间能够较好地连接在一起,而开发人员的思考方式,也会逐步地从单纯的考虑实现,转移到对软件结构的思考上来。这才是测试优先的真正思路。”
  “另外,大家看第(6)步,这里提到了重构。重构是XP里面非常重要的一个实践,只有不断地重构,才能改善代码质量、提高代码复用,它跟TDD/简单增量设计是相辅相成的,谁都离不开谁。那究竟什么时候该重构,什么情况下应该重构呢?”大民把问题提给大家,静候大家的答案。
  “有新功能的时候重构。”txt电子书分享平台 

第11章 你开车,我导航(4)
“需要复用代码的时候重构。”
  “该重构时重构。”
  “写不下去的时候重构。”
  “下一次迭代时重构。”
  大家七嘴八舌地回答。
  大民看到大家差不多说完了,清了清喉咙:“这些想法基本都对。在TDD中,除去编写测试用例和实现测试用例之外的所有工作都是重构,所以,没有重构,任何设计都不能实现。至于什么时候重构嘛,还要分开看,我的经验是:实现测试用例时重构代码,完成某个特性时重构设计,产品的重构完成后还要记得重构一下测试用例。”
  “我刚毕业时,加入的是一家铁路局里的信息部门。我很清楚地记得,;带我的大哥给我的第一句忠告就是‘如果一段代码还能工作,没有出现问题,就不要动它’因为我们做的是铁路调度实时运维系统,不能出一点差错。”小宝喝了口水,接着说,“我觉得非常有道理,一直也是奉行这个金科玉律的。你觉得呢,大民?”
  大民没有马上回答,沉思了一下:“或许在你们的那个环境、那种条件下,这样做是最稳妥的。我想,你们之前肯定因为修改过代码,而导致重大错误,从而一朝被蛇咬,十年怕井绳,对代码产生了恐惧感,最终无法掌控代码。我是这样认为的,如果一个系统一直没有新的需求,使用的情形一直不变,它本身可以一直不变,这样做是可以的。但对于95%的产品而言,是需要不断变化的。如果一些冗余代码、拙劣的代码,存在糟糕的结构和投机性设计,虽然能够正常运行,但这样的软件完全是‘金玉其外,败絮其中’,常常会带来更大的潜在的问题。对于一个负责任的程序员来讲,是不能容忍的。一定要重构,重新优化,夺回对代码的控制权,千万不能滋生得过且过的情绪!”
  阿捷带头鼓起掌来,大家纷纷响应。大民不好意思地咧着嘴笑了。
  等大家静下来,大民接着说:“重构不可避免地会带来一些问题,我们需要建立一个很好的机制来保证重构的正确性。其中很重要的一个实践就是单元测试,是TDD。虽然一些简单的重构可以在没有单元测试的情形下进行,重构工具与编译器自身可以提供一定的安全保障,不至于引入一些简单的人为错误,但如果只采用传统方式对代码进行测试,例如使用调试器或执行功能测试,这种测试方法不仅效率低下,而且是乏味的、不值得信赖的。重构时,代码比以前对修改更为敏感与脆弱。若要避免不必要的问题,则应添加单元测试放到项目中。这样可以确保每一小步的重构,都能够及时发现错误。”
  “这么看,似乎通过TDD就可以发现很多Bug了啊!因为开发人员跟我们测试人员是按照同样的功能验收条件设计测试用例的。我说的没错吧?大民?”阿紫问道。
  “还不能这样说!真正按照TDD的方式进行的软件开发可以非常有效地预防Bug,但不可能通过TDD再找到Bug。因为TDD里有一个很重要的概念是‘完工时完工’。意思是说,当开发人员写完功能代码,通过测试时,工作也就做完了。你想啊,当开发人员的代码完成的时候,即使所有的测试用例都亮了绿灯,这时隐藏在代码中的Bug一个都不会露出马脚来。即使之前没通过测试,那也不叫Bug,因为工作还没做完。”
  “嗯,我明白了!所以还需要我们测试人员同步设计功能测试用例,进行功能验收测试才行。那个阶段,发现的问题才能真正称为Bug。”

第11章 你开车,我导航(5)
大民点了点头,以示认同。
  “我有一个问题,我该为一个功能特性编写测试用例还是为一个类编写测试用例?”小宝问道,“因为从我们的代码中,我看到UT 测试用例都是类和方法。”
  “这个问题很好!我以前也有过类似的困惑。因为关于TDD 的文章都说应该为一个功能特性编写相应的TestCase。后来看了别人的一个Blog,才明白是怎么回事。他们在开始开发一个新特性时,先针对特性编写测试用例,如果发现这个特性无法用测试用例表达,那么将这个特性细分,直至可以为手上的特性写出测试用例为止。然后不断地重构代码,不断地重构测试用例,不断地依据TDD的思想往下做,最后当产品伴随测试用例集一起发布的时候,他们发现经过重构以后的测试用例,就已经是和产品中的类/方法一一对应啦!”
  “哦,是这样。”小宝看上去还是半信半疑。
  “我感觉从功能特性开始是最安全最稳妥的方式,这样不会导致任何设计上重大的失误,也符合简单增量设计、不断重构的XP原则。”大民加上一句,以进一步澄清小宝的迷惑。
  “那么TDD到底该做到什么程度,就算结束了呢?重构总是无止境的。是通过所有的UT测试用例吗?”小宝问道。
  “很简单!Clean Code That Works。”大民抛出来一句英文,看来真的想把大家绕晕才甘心。
  “那到底啥意思啊?你还是说中文吧,听不懂你说的Chnglish。”阿紫打趣道。
  “这句话是TDD的目标,Work是指代码奏效,也就是必须通过所有的UT测试用例,而Clean是指代码很整洁。前者是把事情做对,后者是把事情做好。”
  “关于TDD还有什么疑问吗?”阿捷用目光扫了一遍,见没人响应,接着说,“那我们再来讨论一下结对编程吧。上次我们做Scrum发布计划的时候,曾经提到我们缺少一个人,看看能不能从部门内部临时借调一个人过来,帮帮我们。现在告诉大家的好消息就是,Charles已经正式批准章浩将从下个月加入我们团队,进行TD的研发!”阿捷非常兴奋。
  大民还没等阿捷说完,就插了一句 :“太好了!章浩跟我是前后脚加入Agile的,开发经验很丰富,又熟悉Agile OSS的整个开发环境。嘿嘿,小宝,他来了你再有问题就可以直接向他请教了。章浩人很Nice的。”
  “是啊!自从Charles那回听过咱们的站立会议之后,对Scrum很有好感。再加上咱们前几个Sprint确实做得还行,所以这次Charles听完我和李沙关于TD项目开发任务的汇报后,咱们不是在Resource一栏写着缺少开发人手吗?他看了之后就问我想要谁。我的第一个念头就是章浩!”
  “呵呵,当时说出来还怕Charles不答应,因为章浩毕竟是周小小Team的Technical Leader。Charles当时可没答应我,只是跟我讲他会去和周小小谈谈!谁知道今天早上Charles就告诉我章浩可以下周暂时借调到咱们Team,做完咱们规划的3个Sprint之后,再看情况是否需要回周小小的Team。”阿捷笑着和大家讲述着事情的经过。阿捷并没有和其他人讲其实他在和Charles讲完借调章浩后,曾经独自找章浩谈过近3个小时。
  “哈哈,我说昨天中午在食堂跟章浩
小提示:按 回车 [Enter] 键 返回书目,按 ← 键 返回上一页, 按 → 键 进入下一页。 赞一下 添加书签加入书架