作为管理工具的持续集成

September 3rd, 2010

有一个敏捷推行人,给她的团队设立了一个规则:每个函数不要超过30行。一开始,领导们都说,很好,很有道理。可是真的做起来,就发现遗留代码里有这样那样的特殊情况。紧跟着,开发人员也有了抱怨:我这里写32行又有什么损害呢?为什么一定要那么死板呢?于是,一个又一个的口子被打开。当然,你可以想象,有了越来越多的口子以后,“改善代码质量”也就成了纯理念──跟没有规则之前没什么区别。

我打算怎么做这件事呢?

  • 把持续集成搭起来,只做编译。编译失败就红。红了就不能转测试,红了就必须马上修复,红了就是在阻塞整个团队的工作,红了就是最高优先级。让领导开始盯住持续集成。破坏构建就是和整个团队作对。
  • 大家讨论一下,30行是不是一个合适的门限?如果不是,35行?40行?50行?行。我们就把门限定在50行。把静态检查放进持续集成。旧的代码我们既往不咎。就算现在有100个函数超过50行吧,没关系,我们容忍它。但是如果出现第101个长函数,就会让持续集成变红,要马上修复。
  • 每次构建失败就是一个教育和学习的机会。一个人第一次写出长函数,我跟他一起重构;第二次写出长函数,我要看着他用我教的方法重构;第三次再写出长函数,那就要让领导来关心一下了。没有能力可以学,有了能力还破坏规则,说不过去了吧?
  • 现在大家都学到怎么写更短小的函数了。偷偷把门限降低到45行试试?又多出来10个长函数。拉上几个开发者,我们来搞一次代码优化活动,把这10个长函数解决掉。于是大家又学到了更多的重构技巧。于是45行的门限变成了持续集成的要求。
  • 两周搞一次代码优化学习会,降一次门限值。两个月以后,30行的标准就放在了持续集成里。如果有时间就去重构以前遗留的长函数,如果没时间就留着吧,至少大家已经不会写出新的长函数了。

先讲道理,再定规则,然后帮所有人提升能力以遵守规则,随着能力的提升逐渐拉高规则。30行的规则落实不下去?我就不信了。

把持续集成作为团队规则的自动、可视执行者,于是敏捷推行人就不必扮演那个凶恶的执法者,只需专心帮人排疑解难。持续集成把违规行为变成一个人与整个团队的对立,而不是一个人与另一个人的对立。

Migrating To A Decent SCM

September 1st, 2010

I know that lots of organizations are still using old-expensive-counterproductive configuration management systems (ClearCase, VSS, etc.). I understand the fear that prevents many of them from moving to a decent SCM (Subversion, Mercurial , etc.). I’ll try to tell a story about that kind of migration, which might alleviate the fear.

A huge company, with 40,000+ software developers, with 10+ years history using ClearCase, wants to migrate to Subversion, because of SVN’s encouragement to atomic commit and optimistic locking. The movement is still ongoing. Every single pace involves at least one delivery team, normally with 100+ programmers in it.

The movement must be as seamless as possible, because people are pushed to meet their next milestone. For a codebase sized over 4GB, we made the migration in a week:

  • Monday
    • Export the existing codebase and check it into SVN AS-IS—it’s time consuming so you have enough time for following items.
    • Send mail to everyone to inform the migration plan, ask them to install SVN client if they haven’t.
    • Make sure everyone can access new SVN repository.
  • Tuesday
    • Check out the codebase from SVN and build it, to make sure you are not breaking anything—that’s why you really should migrate AFTER you have a decent build script.
    • Compose a shell script to synchronize from ClearCase local view to SVN working copy. Synchronize frequently and build every time.
  • Wednesday
    • Clean the codebase: legacy repositories often have lots of garbage (temp files, compiled binaries, etc.) checked in, it’s now a chance to do some clearance, delete and ignore them from SCM. Just don’t break the build.
    • Install continuous integration instance for the codebase in SVN.
    • Synchronize and build frequently. Ask people to fix build if it breaks.
  • Thursday
    • Send mail to everyone, ask them to commit any modifications by the end of day, and tell them “there’s an SVN training tomorrow morning”.
    • Keep doing clearance. Synchronize and build frequently.
  • Friday
    • Disable write-access to ClearCase.
    • Training: Configuration Management & SVN. People need to understand some SCM principles to make a better use of SVN—at least not to mess up the codebase with garbage again.
    • At the same time, synchronize a last time, build, check in.
    • Package your working copy and upload it to a shared directory: it’s much faster to copy and unzip, than checking out from the repository. Mail everyone about how to get a working copy and make first commit.
    • Publish your CI to the team. It’s now the team’s CI.

That’s it. Now your team is on SVN.

有效访谈的技巧

August 30th, 2010

你是一个外来者,你想了解一个完全陌生的团队。最快的方式就是找到他们,和他们谈话,让他们告诉你。为了让谈话更有效,你会需要一些小技巧。

  • 解除他们的戒心,尽量。戒心无非来自一个很简单的原因:如果说实话不会有好处、甚至会有坏处,那么人们就不会说实话。因此你要先告诉他们,你需要快速了解信息,不是为了任何考核,只是为了帮助他们改进──告诉他们,你会在未来几个月里跟他们一起改进。
  • 话题明确。每场访谈开始之前,把你要谈的话题写在白板上,以及具体要了解哪些信息,以及计划用多长时间来谈。让进入房间的人在第一时间知道你要他干些什么,这样他就不会更紧张。并且在没话说的时候可以很快找回话题。
  • 微笑。有很多人说过这事,可是真的有很多人没有做到。微笑,活泼一点,拿自己开个玩笑(例如嘲笑自己刚在白板上写下的字)。在访谈中你会必须制造紧张气氛(例如你会有意指出两个人对同一件事的不同描述),保持微笑,把它变成一件好玩的、和所有“人”对立的“事”。不要让任何一个受访者感到寂寞或者紧张,因为这时候你还不知道究竟谁才是值得信赖的人。
  • 记下别人说的话。更多的人说过这事,可是我们真的做得都不好。不要一边跟人对话一边在记事本上写字,更不要用电脑做记录。这些行为会让你获得权威感,会让受访者感到不安──“他有代表权威的记事本/电脑,而我仿佛裸体”──甚至为了抵抗这种不安也拿出记事本来写字。但这些行为不会帮你得到更多有效的信息。在白板上做记录。把他们说的事情画下来。这会让受访者感到,你们在一起画一个作品。他们会告诉你,什么地方画得不对,还缺少了什么,这是你的记事本上永远不会出现的东西。
  • 问他们有什么想告诉你的。当你问完了所有的问题,问他们:还有什么想告诉你的,有什么问题,有什么痛点。你在这里的原因是你要帮助这些人。这些人最关心的事不一定是你最高优先级的事,但一定不是你应该忽视的事。
  • 最后,不要相信访谈。用眼睛去看。受访者一定会告诉你假话。有这样的觉悟之后,访谈才会真正是有效的。

曾经我认为,敏捷的各种实践,只要有了标准化的动作,加上一点点定制,加上PDCA/SDCA,就能做好。迈向敏捷之路,是可以唯一定义并且重复实施的。比如说持续集成,大师说 “在自己的计算机上启动一个自动化build”是重要的──我们把它叫做“本地构建”。做不好本地构建,提交构建失败率就会高,对持续集成的信心就会失去。这个问题,和它的解决方案,都是确定且可重复的。

可是这个团队让我吃惊了。他们一直没有真正意义上的本地构建。但他们真的相信持续集成──不仅仅是几个领导,是整个团队,真的相信:如果每天发现的小问题不能及时解决,那么到版本上线时一定会被客户骂得狗血淋头。他们不想被骂,他们也不想同一个战壕里的战友被骂,所以他们就把持续集成做好了。尽管没有真正意义上的本地构建,就靠着原始简单的代码评审,更认真的态度,他们就真的把持续集成做好了。

这个团队颠覆了一些正在我脑中渐渐成型的东西,让我想起了一些原本印象深刻但被渐渐遮掩起来的东西,比如敏捷宣言的第一条:个体与交互 重于 过程和工具。

面对巨大组织时强烈的无力感、无助感会让“敏捷推行人”们(包括我自己在内)不自觉地选择把自己的定位拔高──也许真是想帮助更多的人,也许只是想从残酷的现实中逃开,抑或两者兼而有之。但这些人不会做高层面的事情。于是离开低层面、离开具体事务的结果就是不知道该做什么,就是把敏捷推行简化为过程和工具的推行。

有一个敏捷推行人对我说,我负责几十个项目的改进,如果每次只到一个项目去做具体的事,对整体的帮助很小。我对她说,也许你救不了所有的鱼,但被你救的这一条鱼,它会在乎 ,它会得救。在反复思考如何拯救所有鱼的过程中,其实你什么也没有做,没有一条鱼真的得救。

敏捷的改变,最终是一个一个的改变。过程和工具会帮助你。但如果把敏捷简化成过程和工具,你就在一步步远离敏捷,因为你已经违背了敏捷宣言的第一条原则。

不做小叮当

July 14th, 2010

ZD亲热地搂着我的肩膀说:“还是你有本事啊,这次才看到你的能力有多强。”我苦笑着说:“我的英名早晚要毁在你手上。”

他是我的客户,也是老乡,而且常常配合很默契。

第一次,二百多人的团队分散在两个城市五个办公地点。ZD对我说,那个产品,发货量巨大,是整个公司最赚钱的部门,客户遍布全球,要是把它搞定了,意义重大。(当时ZB在旁边热情澎湃,被我俩联手泼了一盆冷水。那是我第一次发现,和ZD配合有不需准备的默契。)我沉吟良久,说它真的风险太大,我真的不敢做。但最后我还是去了,因为一个不能让ZD知道的理由。

第二次,一支孤零零的团队正在被一个巨兽客户折磨得要死要活。ZD对我说,这次能让客户感受到我们的变化,要是把它搞定了,意义重大。我又沉吟良久,说它真的真的风险太大,我真的真的不敢做。但最后我还是去了,又是因为一个不能让ZD知道的理由。

我跟他说,其实只是运气好。他笑笑,不信,或者说是装着不信。

小熊说,每个问题解决者都有多拉A梦情结,而康夫每次痛扁技安之后灿烂的笑容便是对小叮当最好的褒奖,是他继续从口袋里掏出法宝的源动力。我不得不承认,挑战一下自己并且挑战成功(不论这成功的原因是什么)的感觉是很爽的。我想ZD一定也知道我的爽感,所以他笑而不语。

所以,尽管真的很想亲眼看到这个大雪球轰然滚下的最后一刻,尽管真的很嫉妒 小熊的博客 比我写得更有料并且更有文采,还是应该抽身了。让自己沉浸在小叮当帮助康夫破涕为笑的愉悦之中,这不是我想要的。

何况,ZD你懂的,我不能等到英名真的毁在你手上的那一天。

对象训练营:简介

July 1st, 2010

对象训练营是 ThoughtWorks 历史悠久的入门培训课程,而其中谈到的对象原则和实践历史就更悠久。面向对象的思想明显地分为两个阵营:

  • Rational。强调建模,推崇UML和形式化方法。这些人最初使用ADA为军方开发软件,系统本身并不复杂。软件正确性非常重要,因此重视对设计的评审。
  • Tektronics,一家电子设备测试工具制造商。强调示波器的可插拔性。使用新的编程语言Smalltalk,因为它的灵活性。这支团队中涌现了Ward Cunningham、Kent Beck、Sam Adams等敏捷世界的大师。使用Smalltalk,他们在设计和编码之间快速切换,这也是现在Agile的基本工作方式。

80年代中期Tektronics团队解散,Sam Adams加入KSC咨询公司,当时在IBM负责与KSC接口的Fred George从他那里学到了Tektronics的对象思想。后来Fred George加入ThoughtWorks,并开创了对象训练营。因此本课程是基于Tektronics的对象思想,而不是Rational的。

本课程采用苏格拉底式教学法,简单说就是学员自己教自己。我们会用问题来引导你,但不会手把手地教你正确答案。你会受阻,但这是好事。正如Fred Brooks所说:“好的判断来自经验,而经验来自糟糕的判断。”记住受阻的时刻,并从中学习,这些经验会成为未来良好判断的基础。

本课程至少3/4的时间会用来给学员自己动手练习编程。如果你喜欢编程,这些练习会很有趣。我们会针对练习中写出的代码展开讨论,所以每次讨论都会把某个pair的代码用投影展示出来供大家讨论。一开始也许你不好意思展示自己的代码,但是请大胆展示。被批评是最好的学习机会。

课程内容分为两大部分:(一)对象原则与敏捷实践,(二)设计模式。

软件开发的最后一英里

在任何软件开发过程中都有一个重要的部分:通过某种构建(build)流程,将已经编写好的源代码变成可用、能为客户创造价值的软件。尽管知道构建的重要性,但是我们仍然会经常因为构建中的各种问题而惊讶不已。曾有多少次,在所有人都认为“开发已经完成”之后,我们还要经历漫长而痛苦的编译、打包、联调、测试、上线过程?在代码都已经写好之后,我们还曾付出了多少个通宵的代价让软件真正可用?

编写源代码不是软件开发的全部。从源代码构建出可用的软件,这个过程也被称为“软件开发的最后一英里”:胜利似乎就在眼前,但各种潜藏的危机可能这段短短的路程变得艰难万分。

持续集成就是构建过程

构建之所以如此困难,是因为在绝大多数软件组织中,构建过程有以下几个特点:

  • 它是一个神秘的、不可见的、只(模糊地)存在于少数人大脑中的过程
  • 它是一个需要人工操作的、耗时费力的、容易出错的过程
  • 它是一个偶尔为之的、缺乏练习的、充满未知风险的过程

为了减少“最后一英里”的浪费,让艰险的最后一英里成为坦途,我们需要将构建过程明晰化、自动化、频繁化。持续集成就是一个将构建过程明晰化、自动化、频繁化的实践。通过使用软件工具来实现自动化的构建过程、展示构建结果,原本虚无的构建过程就成为了一个实际存在的、可以重复进行的、可以被有效管理的实体。从这个意义上来说,持续集成就是构建过程本身:只有以持续集成的形式呈现的那部分构建过程,才是确定并可靠的;“最后一英里”中尚未被纳入持续集成的部分,仍然是不确定和有风险的。

团队空间

June 18th, 2010

Martin Fowler说 ,一个好的团队空间,要有大面的墙作为 信息辐射器 ,团队要围着大桌坐以保持眼神接触,要有自然光线和看到外面景色的落地大窗。

ThoughtWorks北京的办公室,Martin Fowler认为是一个好的团队空间。

这个空间又如何?除了缺少自然光,也是个不错的团队空间。

一只土贼

June 13th, 2010

我承认一开始我认为 小熊 就是一只土贼。有次内部讲session的活动,别人的主题都是有模有样的理论结合实践,小熊搬把凳子往中间一坐,胶片也没有,开口第一句就是很土的话:

“其实搞客户就是将心比心。你想想他的利益是什么,帮他把事情搞定了,他就喜欢你了。”

好吧,确实是很有sense的实话。不过这种没有理论高度的话游沁说也就罢了,作为我司的咨询师用湖南塑料普通话这么讲出来,咋就觉得那么土呢?

广州 呆了一段时间之后我就发现这个小海龟基本上是故意装土,装得很土那么别人就觉得自己很洋于是就愿意跟他嘻嘻哈哈。处女座 在人际关系上的感觉就是特别敏感哈。而且他有两个特别的好处,第一很会 画画 ,第二对 浪费 极其敏感。我最喜欢和这种完美主义强迫症患者一起工作。

然后小熊就搞出了史上最华丽的故事墙。在他的感染下我也搞出了一个华丽的大屏幕CI监视器。并且开始用各种华丽的方式工作,虽然还不如他华丽哈。

今天小熊感到很兴奋,表示我们的工作很有意义,并且立下了要出名的目标。我觉得他可以出名。唯一的缺陷就像(忘了是谁)说 胡适 的:“这个人路子是对的,就是没读过多少书。”我们大部分人都是理论结合实践,他要把实践结合一下理论,拔高一下再写出来,一定会出名。

总之,我觉得这只土贼有可能成为国内最好的敏捷BA。所以我现在开始收集他的签名。

(还有哈,顺便给这个帅锅BA蒸个女盆友~~小熊表示青春痘都冒出来了的日子还是有点造孽~~有意的女童鞋可以找我报名~~)

你是一家大公司里不得志的程序员。和你同年进公司的那些人在核心业务上拼命工作,被客户骂,加班,交付,开庆功会,拿奖金。而你,不知道怎么的被放到一个叫做“测试工具开发”的边角部门里,干着一些不疼不痒不影响公司业绩的工作。你恨。你要报复。你要拿回本该属于自己的一切。

现在我教你怎么做。

首先,你要启动一个自主开发自动化测试工具的项目。让老板们相信自动化测试的重要性并不困难,世界上有无数的文章和书籍在讲这件事,你们公司请的咨询顾问一定也会说到这件事,这些都是你的帮手。真正难的部分是“自主开发”。你用得上一个百试百灵的招数。告诉老板们,一个自主开发的工具可以由自己来维护和支持,只有这样才能把核心技术的命脉掌握在自己手里,而不用向别人支付维护支持的费用──小心,千万不要提到那些开源的工具,因为老板们万一真的弄懂了“开源”这两个字的含义,你的整个大计划就泡汤了。拿IBM的RFT当靶子。除了后面我会说到的各种好处之外,IBM的咨询价格足以帮你吓到老板从而启动这个项目。

然后,你要精心选择一个自动化测试执行引擎。你需要这么一个引擎,因为你不能自己去做一个──工作量还在其次,要是连这都能做,你也就不在这个边角部门里郁闷了。同时这个引擎又不能太稳定,更不能太开放,这都是你大计划中不可或缺的要素。所以,你看,我说过了,RFT就是最好的靶子:它的开放程度确保了你要花好几个月时间才能把它嵌在自己的工具里而且以后再也不会有别人尝试干这件事。而且,想想吧,当你跟老板们报告说你hack了IBM的软件从而省下了licence费用时,他们该有多开心。

接下来,你要发明一套自己的测试脚本语法。沿用RFT的语法当然轻松,但这样使用它的人就会发现自己使用的其实是RFT,然后在该死的互联网上找到相关的资料。不能让这样的事发生。始终记住,你的目标是让自己变得重要。你发明的语法应该基于XML。不仅因为实现简单,而且因为它能确保测试脚本无法被阅读和重构,从而让使用这工具的人跪在你脚边求你支持。关于使用XML的好处,稍后我还会说到。

当然你不希望向领导演示时用记事本编辑XML。所以你得同时实现一个支持拖拽的测试用例编辑界面。把一个测试步骤表示为一个图标,把几个图标往测试用例里一拖,一个测试用例就好了。别忘了,执行用例的功能也得在这个界面里实现。千万别为了偷懒而实现一个命令行来执行用例,这很重要。好了,现在你可以去演示了,领导一定会喜欢的。“鼠标拖拽其实比键盘输入慢多了!”旁边一个傻逼顾问叫喊着。领导们不会听懂他的话。不用理会他,更不要尝试跟他争论,那只会给你自己带来麻烦。

现在这个工具可以小范围试用了。那些麻烦的用户会抱怨:“我每次都要重复这几个同样的操作!我想把它们合并成一个步骤!”镇静。不要骂他们(尽管你一直就想骂他们)。记得吗?让测试用例不可被重构是你大计划中的一部分。现在你要笑容可掬说。我们早就考虑到了这个问题,我们的工具可以把几个步骤封装成一个更大的、具有业务含义的东西……嗯,姑且把它叫做“操作词汇”吧。现在我就来帮助你们做这个抽象和封装。当然了,操作也要用XML来承载,并且在提供给用户时要先做一次编译或者打包或者加密,总之是不能让他们看到源文件。这样他们才能永远依赖你。

小范围试用很重要。你必须努力工作,帮用户写测试用例,帮他们封装操作,找你能找到的一切资源来帮他们,然后把投入二十个人月干出来的成果全都描述成你的工具带来的神奇变化。放心,你只需要这么干一次(或者两次)。为了把这些愚蠢的家伙踩在脚下,有时你就得先纡尊降贵。这是策略。

试用结束,你回到自己的办公室,这些愚蠢的用户还会不停地找你帮忙更新被封装的操作。这是设计中的一环。现在你应该做一个中央服务器,把他们的测试用例和操作全都保存在上面,让他们每次执行测试都从服务器上取用例脚本。然后告诉他们,这叫云计算,这叫测试工厂。当然这些傻瓜不会懂得云计算是什么玩意,但他们会发现你帮他们更新操作的速度变快了,然后他们就会认为这就是云计算带来的效果。把他们感谢你的话搜集起来,很快你就会用得上。

现在万事俱备,可以向老板汇报了。这次汇报的重点是两个关键词。这也是今后宣传这个工具时的常用语。一定要背熟。

关键词1:“第四代自动化测试工具”。你要告诉老板,用Java啦Ruby啦C#啦这些编程语言来编写测试用例,那是第三代(前两代是什么就随便你编吧)。第四代的特征就是“基于操作词汇”──也就是图形界面上可以拖的那个玩意,尽管你知道它背后就是一坨不能读、不能改、连SVN合并都困难的XML。

关键词2:“测试工厂”。这时候把界面打开,连上中央服务器,让老板看试点项目的测试用例。“坐在办公室就能知道所有项目的测试进展情况。”这句话是杀手锏。老板们一定会喜欢,而且会帮你推广这个工具。

只要被推广到更多的项目组,你就会变成红人。现在前面那些设计决策的重要性就逐渐体现了。因为测试用例不可重构,任何一个项目想要正经用你的工具都得找你帮忙做操作词汇,为此你就可以成立一个部门,拉更多的人来给你打这份苦工,自己当领导。但你又怕别人真的用得太多太频繁,那样的话你就得疲于支撑了。放心,因为RFT不稳定,因为每次执行都要连到中央服务器来取用例,因为不能通过命令行或者Ant之类的办法把它放进持续集成,还因为用鼠标拖拽就是比用键盘慢得多,自动化测试的进展会非常缓慢,你大可以安心享受自己的新办公室。

先别急着享受,好事才刚开始呢。那些深思远虑的设计决策确保了很多项目不会认真用你的工具。这时候作为推行先进自动化测试理念的红人,你正好可以在老板耳边吹吹风,让他们强迫所有项目使用。强迫的方式有很多,但你必须记住的手段是给测试人员做职业技能鉴定考试:必须学会用你的工具才能评级加薪。这招的关键在于一箭双雕:不仅可以强迫他们使用,而且确保了他们没时间没动力去了解别的测试工具──你当然不想这些傻瓜突然冒出来说“这个开源的工具比我们自己的好用多了,而且还有那么多社区高手在维护和支持,为什么不用它”,对吧?

强行推广之后,你接到的支撑需求肯定会剧增。这时你得好好培训一下客服的小弟。要让他们分清用户的来头。如果是老板重视的项目,如果办公室离你或者离老板很近,就得大力支持。如果来自什么边远山区的支撑需求,那就把它撂到一边凉快去吧。这些边远山区经常会提些奇怪的需求,例如“能不能不连中央服务器执行用例?我们这里无法连通公司内网”。让小弟们直接回复“不行”就可以了。无法连通公司内网的人同样无法有效地跟领导告状,不用担心他们。

好了。现在你已经从一个边缘程序员成功晋升为公司的红人。不仅有一帮小弟鞍前马后,而且一大帮项目头头们都得求着你优先支撑。这快感,又岂是交付一两个项目、开一两次庆功会所能比拟的?恭喜你。你不仅改变了自己的命运,还很有可能改变整个公司的命运呢。

噢,差点忘了最重要的……千万别用你们的测试工具来给自己的项目做自动化测试。微软那帮傻逼把这种行为叫做“吃自己的狗食”,可你做的是毒药,吃下去会害死自己的。切记,切记。