编程道场 (Coding Dojo) 进行操练和 TDD 常见问题、难点

编程操练,就是个人或多人在一起刻意练习测试驱动开发(Test-Driven Development, TDD),来锻炼程序员的测试先行、测试用例设计、小步代码提交、重构代码、提升代码质量、反复操练同一题目寻求更佳实现方法、结对编程等能力。编程操练不求完成率、不求编程速度、但求共同领悟软件开发之道。

编程操练的形式一般分3种:

1)Code Kata 编程招式:单人操练编程招式(即有趣的编程题目);
2)Coding Dojo 编程道场:多人在半天内,于编程道场中结对进行编程操练;
3)Code Retreat 编程静修国际日:在coderetreat.org的组织下,全球各个城市多人在每年感恩节前的同一个周六的一天内,于编程道场中结对进行编程操练;
4)新增一种线上结对的方式,使用 zoom.us 或其他视频会议工具来实时交流获得接近面对面的体验

编程操练的种类一般分3种:

1)从零开始用TDD写代码;
2)将遗留代码用TDD重构到设计模式;
3)将遗留代码用TDD重构到函数式编程;

编程操练常用的Kata:FizzBuzz(适合TDD初学者入门)、Anagrams(适合体验TDD如何通过小步重构驱动出递归算法)、String Calculator(适合体验编程时如何满足SOLID设计原则)、Gilded Rose(适合体验重构到设计模式或函数式编程)、Ticket Dispenser(适合体验如何编写mock来解除耦合进行单元测试)、Game of Life(适合编程静修)。

编程道场中的参加者只要携带自己安装好开发测试环境的笔记本电脑来就好了。

+编程道场之前:

1)编程道场之前,先联系场地赞助方,确定好时间、地点、带有投影仪的能容20人的办公室;
2)发布并推广活动报名信息,推荐使用微信公众号来发布,请参加者们加组织者的微信,建微信群,更加方便互动;
3)确定一位联系人的电话,为找不到活动地点的参加者提供方便;
4)活动需要操练的Kata自己最好能操练熟练,为引导参加者做准备;
5)在自己的电脑上安装Cyber-dojo私服,供参加者使用,可以带一个无线路由器以备场地wifi不给力;
6)用挂纸写出Kata内容,以便参加者编程时参考;
7)提前30分钟到场做准备,贴挂纸,测试网络;
8)准备一些报事贴和白板笔,供最后回顾时使用;
9)可带一个激光笔备用。

+编程道场期间:

1)请大家自我介绍;
2)介绍Kata;
3)参加者报数分组,结对编程用Cyber-dojo编写kata,组织者此时可以拍照以便写回顾文章;
4)用Cyber-dojo来分享与讲解参加者的代码;
5)参加者重新报数分组,结对编程用Cyber-dojo重新编写kata;
6)用Cyber-dojo来分享与讲解参加者的代码;
7)回顾:参加者各自在报事贴上写“本次活动的收获”、“本次活动需要改进的地方”、“疑问”,然后分类贴在墙上,组织者在各位参加者面前朗读报事贴上的内容,必要时请写报事贴的人解释一下,进行回顾;
8)大家鼓掌感谢场地赞助方,场地赞助方此时可以植入一些简短的广告。

+编程道场之后:

1)组织者尽快撰写本次编程道场的回顾文章,会议纪要形式即可,要附上活动现场照片,以便今后做进一步的市场推广;
2)可以建域名和网站来存放回顾文章,我使用godaddy.com来申请域名和建站;
3)可以建微信公众号来发布下一次活动报名信息;


参考 http://www.bjdp.org/ (北京设计模式学习组 Home)

dojo是你维护的呀?

TDD (测试驱动开发) 常见问题

TDD (测试驱动开发) 常见问题 » Topics » 中国软件匠艺小组

刚写了一个测试,还没写实现。明知道运行测试一定会报错,为什么还要去运行?

其实测试的运行结果并非只有通过与不通过两种,因为不通过时有很多种可能。所以在明知道一定失败的情况下去运行测试,目的是看看是不是报了期望的那个错误。

小步快走确实好,但真的需要这么小步吗?

步子迈太大,容易扯着蛋。
练习的时候需要养成小步的习惯,工作的时候可以自由切换步子的大小。
当你自信的时候步子就可以大点,当你不太自信的时候就可以立即切换到小步的模式。
如果只会大步,就难以再小步了。

测试代码是否会成为维护的负担?

维护时也遵循TDD流程,先修改测试代码成需求变更后的样子,让测试失败,再修改产品代码使其通过。
这样你就不是在维护测试用例,而是在利用测试用例。

为什么要快速实现?

其实是用二分查找法隔离问题,通过 hardcode 实现通过测试后,就基本确定测试是没有问题,这时再去实现产品代码,如果测试不通过,就是产品代码的问题。
所以小步快走主要是为了隔离问题,也就是你可以告别 Debug 了。

为什么测试代码要很简单?

如果一个测试失败了,修复的时候是改测试代码而不是产品代码,那就是测试代码写的不好。
当测试代码要足够简单,如果一个测试失败了,就有足够信心断定一定是产品代码的问题。

TDD 为什么这么难? » Topics » 中国软件匠艺小组

读到同事张逸的一篇博文:推行TDD的思考,我也有感而发。
我刚加入ThoughtWorks时,工作在一个合作开发的Android项目上,我们除了要TDD外,也要求并指导客户公司的开发人员进行TDD,项目开发了快半年,测试覆盖率稳定在90%以上。
业余时间,我主持过GDCR和Coding Dojo等活动。不管在企业还是社区,我见到很多开发者对TDD的理解还停留在字面上。
我认为推行TDD主要在两个方面努力,即意识和能力(好像任何事情都是这两方面哈)。

意识方面主要是:

  • 认识到自己原有编程方法的不足;
  • 搞清楚TDD的价值所在,如何弥补原有方法的不足;
  • 心态开放,勇于尝试新鲜事物,不要浅尝辄止,要持续改进。

意识和能力没有先后关系,而是在不断学习和实践过程中同时提高。在这篇文章中,我更想谈的是能力。
我见到初接触TDD的人常犯下面的错误:

  • 在声明测试方法后,便开始写实现代码;
  • 写完“所有”的测试代码才开始写实现;
  • 一次实现过多的代码(超出当前测试覆盖的业务);
  • 从不重构;

TDD真是看起来容易,做起来难。

image

上面这个图一目了然,但其实每一步都是对能力有要求的:


测试先行并不是说不需要思考,直接开始写代码。在开始写代码之前要进行需求分析,将需求分解为任务列表,再从列表中挑选一个任务,转换成一组测试用例,然后不断循环去实现。测试代码其实是产品代码的“用户”,在写测试代码时你就要考虑如何“使用”产品代码,是一个实例方法还是一个类方法,是从构造函数传参还是从方法调用传参,方法的命名,返回值等。这时其实我们就是在做设计,而且设计以代码来体现,比在脑袋中空想要更直观。很多人不懂“意图式编程”,总是习惯先实现一个东西,再去调用它。而测试先行就要求先使用,再实现。这样能少走很多弯路,减少返工。

绿


以最快的速度让测试变绿,意味着我们通常用最直接但可能并不优雅的方式,比如复制代码。然后小步重构,直到符合简单设计的原则:

  1. 通过所有测试
  2. 每个概念都被清楚地表达
  3. 没有重复
  4. 没有多余的东西

难的是要让实现刚好满足当前的测试,不做过度的设计,不写多余的代码。因为如果你写多了,除了引入复杂性以外,多的那部分就没有测试能覆盖到。或者你后面的测试写出来就能直接变绿,你就没办法按TDD的节奏进行下去了。

重构


首先要能识别坏味道,一些低级的Smell,很容易识别,比如:Magic Number,重复代码,太大的类,太长的方法,命名等。但更高级的如Feature Envy,Lazy Class等就比较难以识别。

只要识别到Smell,知道用什么手法去重构,剩下的就比较简单了,现代的IDE,尤其是JetBrains的产品,对重构的支持非常强大,几乎都可以用快捷键完成。选对工具非常重要,善假于物能极大提高开发效率。但也不能过分依赖工具,要明白每一个手法背后的原理。所以推荐每个想要实践TDD的开发者,一定要先读《重构》。


最后我想说:
TDD不是银弹,不可能适合所有的场景,但这不应该成为我们拒绝它的理由。
也不要轻易否定TDD,如果要否定,起码要在认真实践过之后。