购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第10章
持续集成,降低集成的痛苦

Agile作为美国最大的通信公司之一,采用的是目标管理(MBO)体系。目标管理(MBO)的概念是管理专家彼得·德鲁克(Peter Drucker)1954年在其名著《管理实践》中最先提出的,其后他又提出“目标管理和自我控制”的主张。德鲁克认为,并不是有了工作才有目标,而是相反,有了目标才能确定每个人的工作。所以“企业的使命和任务,必须转化为目标”。如果一个领域没有目标,这个领域的工作必然被忽视。因此,管理者应该通过目标对员工进行管理,当组织最高层管理者确定了组织目标后,必须对其进行有效分解,转变成各个部门及每个人的分目标,管理者根据分目标的完成情况对下级进行考核、评价和奖惩。

目标管理提出时,时值第二次世界大战后西方经济由复苏转向迅速发展的时期,企业急需采用新的方法调动员工积极性以提高竞争能力,目标管理的出现可谓应运而生,遂被美国企业界广泛应用,并很快为日本、西欧国家的企业所仿效,在世界管理界大行其道。

目标管理指导思想上是以Y理论为基础的,即认为在目标明确的条件下,人们能够对自己负责。它与传统管理方式相比有鲜明的特点,可概括如下。

1. 重视人的因素

目标管理是一种参与的、民主的、自我控制的管理制度,也是一种把个人需求与组织目标结合起来的管理制度。在这一制度下,上级与下级的关系是平等、尊重、依赖、支持的,下级在承诺目标和被授权之后是自觉、自主和自治的。

2. 建立目标锁链与目标体系

目标管理通过专门设计的过程,将组织的整体目标逐级分解,转换为各单位、各员工的分目标。从组织目标、经营单位目标,再到部门目标,最后到个人目标。在目标分解过程中,权、责、利三者已经明确,而且相互对称。这些目标方向一致,环环相扣,相互配合,形成协调统一的目标体系。只有每个个人完成了自己的目标,整个企业的总目标才有完成的希望。

3. 重视成果

目标管理以制定目标为起点,以目标完成情况的考核为终结。工作成果是评定目标完成程度的标准,也是人事考核和奖评的依据,成为评价管理工作绩效的唯一标志。至于完成目标的具体过程、途径和方法,上级并不过多干预。所以,在目标管理制度下,监督的成分很少,而控制目标实现的能力却很强。

阿捷觉得MBO跟Scrum在思想上是相通的,所以对这个管理方法具有好感。与此同时,他也了解到,在英特尔和谷歌等公司,已经把MBO延伸成了OKR。MBO更多的是从上往下,而OKR则是提倡员工自我驱动,属于由下向上,符合组织扁平化、阿米巴化的趋势。无论哪个方法的O(目标),如果想要很好的落地,都要遵循如下的三个原则,而谷歌在这方面的尝试值得借鉴。

1. 可量化的O

O应该是可量化的,要符合SMART原则,比如不能说“使Gmail达到成功”而是“在9月上线Gmail并在11月有100万用户”。在谷歌,最多5个O,每个O最多4个KR(关键成果)。

2. 有挑战的O

O应该是有野心的,有一些挑战的,有些让你不舒服的(按照谷歌的说法,完成挑战性目标的65%要比100%完成普通目标要好)。正常完成时,以0~1.0分值计分,分数0.6~0.7是比较合适(这被称为sweet spot,最有效击球点);如果分数低于0.4,你就该思考,这个项目究竟是否需要继续进行下去。要注意,0.4以下并不意味着失败,而是明确什么东西不重要及发现问题的方式。这与KPI要求“跳一跳够得着”类似。

3. 透明化的O

O及Key Results(关键成功)需要公开、透明、可视化的管理,每个人都可以了解到其他人的目标,当你能够看到同级、上级或者老板的目标时,你才可以校检你的方向是不是跑偏。

在Agile公司,目标管理有固定的一套程序或过程,它要求组织中的上级和下级一起协商,根据组织的使命确定一定时期内组织的总目标,由此决定上、下级的责任和分目标,并把这些目标作为组织经营、评估和奖励每个单位和个人贡献的标准。为了更好地检查目标完成情况,上级和下级要定期会晤,讨论进展和问题。在Agile公司,这种定期会晤称为One to One Meeting(1对1会议),是经理跟员工一对一地进行。

阿捷自从接管TD这个团队后,与员工制定并讨论MBO,已成了他每个季度的必修课。阿捷发现,MBO/OKR关注的是组织与个人目标和价值的管理,Scrum关注的是价值驱动的交付,关注的是目标实现。OKR和Scrum结合能够更好地保证目标实现。如果把KR转换为Scrum的Backlog,正好可以分阶段、分迭代实现。当然,MBO/OKR不是KPI,不是用来做考绩效核的,重点是能够让团队关注目标、关注重要的事情,而不只是围着考核相关的数字、公式转。通过OKR的透明化管理,把公司的目标、每个人的目标公开化、可视化呈现出来,相互监督,共同努力实现目标。在这样的高度透明的环境下,谁的表现如何自然很清楚,这样为团队的相互评审提供了良好的基础。这样的做法和Scrum的透明性是完全一致的。

因为团队正在实施Scrum,阿捷跟阿朱一起设定的目标之一就是“如何做到测试的敏捷化”。

Objective目标:如何做到测试的敏捷化

KRs:做全新的版本,需要的回归测试时间从3天降到1天。

KRs:每次构建打包的时间,从3小时降到1小时。

KRs:自动化测试的比率,从50%提升到70%。

KRs:保证当前迭代内的功能,完成100%的测试。

阿捷率先开头:“我们之前也做过几轮的1对1了,你对这个事情本身有什么建议吗?”

“嗯,”阿朱略微沉思了一下,“反馈要及时,目标设定要随时调整。其实,我对以年为跨度的目标设定和绩效评估的最大困惑就在于两者的严重脱节。”

“哦?”阿捷示意阿朱继续。

“实际上,这样长跨度的目标设定,更倾向于一个职业发展计划而不是目标计划。而拿一个职业发展计划作为年终绩效评估的依据,似乎不怎么合理。”

“嗯”,其实阿捷也有同感,之前几年,袁朗跟阿捷1对1的沟通,最终多数沦为了形式,阿捷也准备做些改变。不过阿捷还是鼓励阿朱说下去,“你觉得怎么改更好?”

“我是这么想的,我们实施敏捷开发有一段时间了,一个Sprint的周期基本是3周左右,那么我们每人的短期目标完全可以跟每个Sprint结合起来。因为每个Sprint的目标都很明确,再落实到每个人头上就会非常实际。但这样,就得加强沟通的频率,及时调整目标。”

“你的意思是说我们把每个季度一次的1对1沟通,改成每个Sprint一次?”

“对!”

“嗯,你说得非常有道理,我也有同感。可以把每年的目标设定,作为员工个人的发展计划。怎么样?”

“不知道别的员工怎么想,我觉得这样做会更有价值。只不过,你就得多花些时间在这上面了。”阿朱笑着说。

“这倒没关系!关心并帮助每个队员的职业发展,本来就是我的责任。我会再做一个调查,了解一下其他人的看法。你今天提出来,非常好!”

阿捷抬头看了一下墙上的表,还有半个小时的时间,得赶紧讨论这次的主题了。“接下来,看看我们上次提到的敏捷测试,你有什么最新进展吗?”

“我这几天思考了一下,我觉得我们的项目有必要采用XP(极限编程)的持续集成。”

阿朱针对自己的“敏捷测试”目标,提出了自己的想法。

“为什么要持续集成?”阿捷问。

“你看,我们现在的开发模式是项目一开始就划分好了模块,等所有的代码都开发完成之后再集成到一起进行测试。随着需求越来越复杂,咱们已经不能简单地通过划分模块的方式来开发,需要项目内部互相合作,划分模块这种传统的模式的弊端也越来越明显,由于很多Bug在代码写完时就存在了,到最后集成测试的时候才会发现问题。我们测试人员需要在最后的测试阶段帮助开发人员寻找Bug的根源,因为间隔时间久,改动代码累加,花费时间就更久,再加上咱们系统的复杂性,问题的根源很难定位,甚至出现不得不调整底层架构的情况!”

“是啊,所以好多团队在这个阶段的除虫会议(Bug Meeting)特别多,会议的内容基本上都是讨论Bug是怎么产生的,最后往往发展为不同模块的负责人互相推诿责任,开发测试不断打架。”

“通过持续集成,可以有效地解决这个问题。”

“具体该怎么做呢?”阿捷拿起笔,准备记录。

“你看我们的开发、测试流程,当任何一个人修改代码后,首先运行单元测试;通过后,提交代码;构建产品;把它放在模拟的产品运行环境下,进行测试;遇到问题,进行修正并重复上述过程。现在我们需要做的,是让上述过程自动化。”

“嗯,这样肯定可以大幅提高开发测试效率。”阿捷表示赞同,并示意她继续讲下去。

“我觉得需要做这样几件事情:编译自动化、单元测试自动化,再加上自动化打包、自动部署到测试环境,然后自动进行功能测试、性能测试!”

“我觉得还有必要加上一条,自动统计测试结果,并通过邮件发送给相关的人。有了这样的一个框架,你们测试人员就可以从一些烦琐的手工劳动中解放出来,做真正有意义的事情了。”阿捷补充了一句。

“嗯,有道理。”

“看来关键是如何实现完全的自动化,从读取源代码、编译、链接、测试,整个构建过程都应该自动完成。对于一次成功的构建,我们要做到在这个自动化过程中的每一步都不能出错。”

“这么一来,也就不需要专人做Build Manager(构建经理)了!我总算解放了。”阿朱对这个想法的实施,肯定已经神往已久了。

“嗯,具体的工作是不需要你亲自动手了,但是策略性的东西,还得你把关。譬如软件配置管理(SCM)、分支/合并策略、软件发布通知(Release Notes)等。”

“这些工作不需要经常做的。我会搞好的。”阿朱笑着说。

“不过,上面所说的持续集成过程,实际上要求开发过程也要有对应的改变,譬如自动单元测试那块,应该由开发人员负责。”

“对,因为这不再是传统的编译那么简单,属于自测的范畴。自测的代码是开发人员提交源码的时候同时提交的,是针对源码的单元测试,将所有的这些自测代码整合到一起形成测试集,在所有的最新的源码通过编译和链接之后,还必须通过这个测试集的测试,才能算是一次成功的构建。”

“这好像就是麦康奈尔(McConnell)提出的‘冒烟测试’吧。”阿捷突然想起了曾经看过的一篇文章。

“对!这种测试的主要目的是为了验证构建的正确性。在持续集成里面,这叫构建验证测试(Build Verify Test,简称BVT)。我们测试人员按理不会感受到BVT的存在,我们只针对成功的构建进行测试,如功能测试。”

“嗯,这些我会跟大民和小宝他们说,让他们去实现。”

“那我和阿紫负责其他部分的自动化功能测试框架。”

“我还有一个问题,持续集成和每日构建有什么关系?二者是不是一个东西?”阿捷绝对不会放过任何一个学习的机会。

“有些不同。持续集成强调的是集成频率。和每日构建相比,持续集成显得更加频繁,目前业界的极致实践是每一次提交代码就集成一次。持续集成强调及时反馈。每日构建的目的是每天可以得到一个可供使用的发布版本,而持续集成强调的是集成失败之后向开发人员提供快速的反馈,当然成功构建的结果也就是得到可用的版本。每日构建并没有强调开发人员提交源码的频率,而持续集成鼓励并支持开发人员频繁提交对源码的修改并得到尽快的反馈。”

“噢,重点就是‘频率’和‘反馈’两个方面。”阿捷若有所思。

“对!持续集成有一个与直觉相悖的基本要点,那就是‘经常性的集成比偶尔集成要好’。对于持续集成来说,集成越频繁,效果越好,如果集成不是经常进行的,比如少于每天一次,那么再集成就是一件痛苦的事情,也就是我们过去及现在一直遇到的问题。”

“我想,创建一个持续集成的环境,技术上是比较复杂的,也需要一定的时间,但长期回报肯定是巨大的。”阿捷带着询问的眼光瞅着阿朱。

“没错!只要我们能够让持续集成‘及时’抓到足够多的Bug,从根本上消除传统模式的弊端,这就已经很值得为它所花费的开销了。”阿朱非常期望这项工作马上开工:“那我们需要赶紧开一个会议,大家统一一下认识,做一个分工,然后分步实施。”

“嗯!这个任务我就交给你了,怎么样?”

“没问题!”

阿捷预感到,持续集成这个想法如果得到实施,那将是开发效率的一次巨大突破。

在他人眼里,像阿捷这样高学历、高薪水、出入高档写字楼的“三高”白领单身人士,身边一定会有很多女孩子。其实阿捷的生活完全不是别人想象的那样。虽然不知道自己还能有多久告别单身生活,可是阿捷并不着急。因为他一直崇尚这样一句话,“宁愿高傲地发霉,也不要委屈地谈恋爱”,忘记这是谁的QQ留言了,但享受生活的阿Q精神是必不可少的,要在平淡的生活中用自己的生活方式来享受人生,去品尝大千美食,去饱览世间万象。因而,阿捷的业余生活非常丰富,不仅经常去北师大踢踢球,顺路饱饱眼福,他还是“绿野”的会员,从“香巴拉”拉练到灵山黄草梁穿越,北京周边都留下了阿捷的足迹。

周末,对于阿捷这种光光人士来说,既好过,又不好过。好过的是孤家寡人,想做什么就做什么,非常自由;不好过的是偶尔感觉到一点孤独,特别当自己的狐朋狗友抛开自己,跟女朋友出去约会的时候,只有忠实的小黑安静地趴在自己的腿边,陪着阿捷打CS游戏。

自从接触了敏捷开发,阿捷的周末生活已经慢慢有了些变化,从原来的遛完小黑就开始无聊地打CS,到每天都泡在网上如饥似渴地学习Scrum。而敏捷圣贤的出现,则让阿捷多了一份期待。那种似师似友的感觉很奇妙,敏捷圣贤常常在全球各地旅行,更让喜爱旅行的阿捷羡慕不已。这天在网上,阿捷又遇见正在德国做咨询的敏捷圣贤。

阿捷: Hi,你好!圣贤,德国玩得怎么样?现在在哪儿呢?

敏捷圣贤: 嘿,哪有你说得那么轻松,我这可是工作的一部分。我现在在慕尼黑。

阿捷: 不错!我喜欢那个城市,因为有德甲最伟大的球队,拜仁慕尼黑。

敏捷圣贤: 你喜欢哪个球星?

阿捷: 当然是小猪了!

敏捷圣贤: 施魏因斯泰格?我可以帮你带一件他签名的球衣!

阿捷: 真的?

敏捷圣贤: 真的!

阿捷: 我都不知道怎么感谢你好了!

敏捷圣贤: 不用这么客气呀,举手之劳的。

阿捷: 嗯,对你可能是,但对我却不是……无论如何,我要好好感谢你才对,不仅在这件事情上,你在项目管理上对我的帮助,也使我受益匪浅。

敏捷圣贤: 其实,我从你们的实践中也获得了很多值得思考的东西。对了,最近你们怎么样?有没有试验一下其他敏捷实践?

阿捷: 持续集成(CI,Continuous Integration)。

敏捷圣贤: 这是一个非常好非常有用的XP实践!它可以有效地降低风险,但是它对与开发相关的日常活动提出了很高的要求。你们现在做到什么程度了?

阿捷: 才刚刚开始!有什么需要注意的吗?

敏捷圣贤: 哦,我以前的团队实行持续集成时,遇到过很多问题。在后来,我遇到保罗 · 达瓦尔(Paul Duvall)博士,才知道我们错误地采用了一些持续集成的反模式(anti-pattern)。

阿捷: 保罗 · 达瓦尔?反模式?

敏捷圣贤: 他是 Stelligent Incorporated 的 CTO,该公司是一家咨询公司,在帮助开发团队优化 Agile 软件产品方面被认为是同行中的翘楚。反模式这个词,表示在特定环境中不应该采用的做法。反模式最终可能产生严重影响。

阿捷: 看来是一位大师啊!都有哪些做法是反模式?这对于我们这样一个缺少持续集成经验的团队,应该是非常有帮助的。

敏捷圣贤: 他主要讲到了六个反模式:第一个是代码提交不够频繁,导致集成延迟。也就是说,如果代码长期滞留在开发人员自己手中,没有及时提交,如果其他人对系统的其他部分做出修改,而修改可能会相互影响的话,集成就会延迟;延迟越长,消除其影响就越困难。

阿捷: 看来必须要求开发人员每天至少提交一次。

敏捷圣贤: 对。把任务划分得越小,越容易完成,开发人员才能越容易地经常性提交。第二个反模式是经常性构建失败,使团队无法进行其他任务。

阿捷: 嗯,这个问题对我们影响比较小!我们在将代码提交到存储库之前,先在存储库中更新代码,再运行私有构建(Private Build),保证构建成功后,才能提交。万一构建失败,就要指定专门开发人员并以最高优先级尽快修复。

敏捷圣贤: 你们做得不错!第三个反模式是构建反馈太少或太迟,使开发人员不能及时采取纠正措施。我想你们也应该问题不大。

阿捷: 对,我们对每次构建结果都会发送邮件给全体人员。

敏捷圣贤: 嗯,第四个反模式是垃圾构建反馈太多,使得开发人员忽视反馈消息。这一点跟前一点是相对应的。我觉得你们应该改进一下。

阿捷: 哦?

敏捷圣贤: 你们现在每个人都会接到反馈的电子邮件。邮件一多,大家很快就会将持续集成反馈看作垃圾邮件,进而忽略它们。你们需要指定一个人专门负责检查关于构建的邮件。只有构建失败时,才把邮件发给引起失败的人,这样大家才会重视。

阿捷: 嗯,有道理,值得改进。

敏捷圣贤: 第五个反模式是用于进行构建的机器性能太低,导致构建时间太长,严重影响频繁地执行集成。

阿捷: 我们有5台超强的HP-UX服务器,可以实现自动负载分担,并行构建!再加上我们的优化,每次构建不会超过半小时。

(一说到这些,阿捷还是很自豪的,Agile公司财大气粗,硬件环境绝对一流。)

敏捷圣贤: 嗯,真羡慕你们公司!最后一个反模式是膨胀的构建,导致反馈延迟。

阿捷: 膨胀的构建?

敏捷圣贤: 譬如,把太多的任务添加到提交构建过程中,比如运行各种代码自动检查、统计工具或运行性能测试,从而导致反馈被延迟。

阿捷: 噢,这个我们倒是应该引起足够的警惕。

敏捷圣贤: 其实,还有其他一些反模式的,这些持续集成CI反模式会妨碍团队从持续集成实践中获得最大的收益,所以一定要想办法限制这些反模式发生的频率。

阿捷: 是啊!对我们没有多少持续集成经验的团队来说,持续集成像一块吊得很高的目标,看得见却摸不着。要做好持续集成并不容易,但我们可以使用持续集成的思路,来接近持续集成的目标。

敏捷圣贤: 嗯,加油!我有点事情,先下去了。再见!

阿捷: 再见!

本章知识要点

1. 持续集成最大的优点之一是可以避免传统模式在集成阶段的除虫会议。持续集成强调项目的开发人员频繁地将他们对源码的修改提交到一个单一的源码库,并验证这些改变是否给项目带来了破坏,持续集成包括以下几大特点。

· 访问单一源码库。将所有的源代码保存在单一的地点(源码控制系统),让所有人都能从这里获取最新的源代码(及以前的版本)。

· 支持自动化创建脚本。创建过程完全自动化,任何人只需要输入一条命令即可完成系统的创建。

· 测试完全自动化。要求开发人员提供自测试的代码,让任何人都可以通过一条命令就运行一套完整的系统测试。

· 提倡开发人员频繁地提交修改过的代码,一天至少一次。

2. 项目Bug的增加和时间并不是线性增长的关系,而是和时间的平方成正比。两次集成间隔的时间越长,Bug增加的数量越多,解决Bug付出的工作量也越大;你越觉得付出的工作量大,越想推迟集成,企图最后一次性解决问题,结果Bug更多,导致下一次集成的工作量更大;你越感觉到集成的痛苦,就越将集成的时间推后,最后形成恶性循环。

3. 有效限制持续集成(Continuous Integration)反模式如下建议。

· 频繁提交代码,可以防止集成变得复杂。

· 在提交源代码之前运行私有构建,可以避免许多失败的构建。

· 使用各种反馈机制避免开发人员忽视构建状态信息。

· 有针对性地向相关人员发送反馈,这是将构建问题通知团队成员的好方法。

· 购买更强大的构建机器,优化构建过程,从而加快向团队成员提供反馈的速度。

· 避免构建膨胀。

冬哥有话说

痛苦的事情反复做

开发中最痛苦的事情是什么?集成、测试、部署和发布。极限编程以及持续交付的理念,就是提前并频繁做让你觉得痛苦的事情。

从某种程度上讲,持续集成是反人类天性的。由于集成很痛苦,人们便会本能地抗拒和拖延。如同锻炼身体一样,过程会很痛苦,但对身体健康是有益的。持续集成也是一样,开始的过程会痛苦,坚持下来,对研发的健康度有极大帮助。

敏捷开发强调节奏,Sprint的迭代以几周为单位,每日站立会议是以天为单位,而持续集成则是以小时和分钟为单位的,它是敏捷开发以及DevOps的心跳。

持续集成

“如果集成测试重要,那么我们将在一天中多次集成并测试”,这是极限编程中的建议。集成的目的是测试,测试的目的是反馈,反馈的目的是给开发者信心。

如前所述,推迟集成,会造成恶性循环;而持续集成实践,可以有效抑制缺陷蔓延。缺陷发现越晚,成本越是会几何倍数增长;我们都知道切换的成本,让开发人员从一个任务中抽离,切换思维去回忆几周甚至数月前修改的代码引入的缺陷,是极其低效的。

马丁·福勒(Martin Fowler)在他的博客(http://martinfowler.com/articles/continuous Integration.html)上描述了对持续集成的建议:

· 只维护一个源码仓库

· 自动化build

· 让你的build自行测试

· 每人每天都要向mainline提交代码

· 每次提交都应在集成计算机上重新构建mainline

· 保持快速build

· 在类生产环境中进行测试

· 让每个人都能轻易获得最新的可执行文件

· 每个人都能看到进度

· 自动化部署

而Jez Humble在其所著的《持续交付》一书中,推荐了在使用持续集成时必不可少的实践:

· 构建失败之后不要提交新代码

· 提交前在本地,或持续集成服务器,运行所有测试·提交测试通过后再继续工作

· 回家之前,构建必须处于成功状态

· 时刻准备着回滚到前一个版本

· 在回滚之前要规定一个修复时间

· 不要将失败的测试注释掉

· 为自己导致的问题负责

· 测试驱动的开发

Scrum与MBO/OKR

阿捷独创地将Scrum和MBO/OKR进行关联的做法,非常有意思。将团队和个人的目标,与Scrum的目标与产出有机结合,并通过Scrum过程监控,可视化进行有效追踪,随时反馈并调整。如果OKR中的Object是Epic(史诗),那么KRs就是Feature(特性),进一步可以拆分成一个迭代可以完成的Story(故事)以及Task(任务)进行实现。

需求有业务类的,有技术类的,目标也是一样,同一个Sprint迭代中,应该设置一定比例的技术类需求,持续对技术债务进行清理。

爱德华·戴明认为绩效考核、绩效排名以及年度考核是管理上七大顽疾之一。考评应该偏重团队而不是个人,就像球队一样,团队应该为了统一的目标而努力。频度上应该以季度甚至更短,个人和团队的目标及绩效应该设置阶段检查点,并随时根据结果进行沟通,而不是到年度绩效出来以后,再告诉员工绩效结果。绩效考评的目的是为了员工的成长和改进,而不仅仅是监督与批评,更不是开除员工的借口;考评即要面向结果,也要面向过程,避免为短期结果而牺牲长期利益而走捷径的方式。

OKR最早起源于英特尔,因约翰·杜尔在谷歌的建议推广而闻名天下。OKR的实施,应该是自上而下来制定,并同时保持自下而上的沟通;自上而下,公司的目标逐层拆解到个人目标;自下而上,个人目标要不断地与公司目标对齐,更容易调动员工的个人积极性。好的目标Object,应该是使劲跳能够到,要有一定的挑战性,100%都能完成的只能表明目标平庸。OKR不是KPI,不要与绩效进行挂钩。

精华语录

________________________

________________________

________________________ YxD5Kf4TBncyJorTdOdcqQ6HbX9tQ5kLPaDqsXKu2YmDcbOvWz+zOTb5PVKaP4dz

点击中间区域
呼出菜单
上一章
目录
下一章
×