(本文发表于《程序员》2010年3月刊)
借鉴丰田方法对大型软件组织进行敏捷改造 (上)
本文以 ThoughtWorks 中国公司与 某大型 电 信 设备 提供商 合作的 咨询项目 案例 为 背景 , 介 绍 如何采用丰田倡 导 的精益生 产 方法 对 大型 软 件 组织进 行敏捷改造,从而有效提升其交付能力。
背景
QWS是一款电信交换机产品 ,其软件部分用C语言开发。 经过长期的发展演化,当本文所述的咨询项目开始时,QWS的总体代码量已经超过2000万行 ,代码库体积超过4GB 。 本咨询项目所 涉及 的 版本需要新开发的代码量约90万行。
QWS的版本 交付 团队 大致由90名左右开发人员和30名左右测试人员组成。这支交付团队又按特性和模块划分为6个特性团队和2个任务团队,共计8个子项目组。 每个项目组分别有一个SVN工作分支,项目组成员将代码提交到分支,项目经理再负责将分支代码合并到主干。
在 ThoughtWorks 顾问组进入该团队 之 时 , 这支多年沿用CMM 方法的团队正在自行尝试敏捷方法, 刚刚 开始第一个为期3周的迭代。 但 这第一个迭代远非一帆风顺。 一方面,由于团队从来没有迭代交付的习惯,开发人员在编码阶段忽视质量,导致提交到SVN的代码有时甚至不能编译,即使编译出软件大包也存在严重功能缺陷,无法进行测试;另一方面,由于团队成员对SVN缺乏了 解,多个分支的配置管理遇到了极大的困难。
就在这样一种混乱的状态中, 由3名 ThoughtWorks 咨询师组成的顾问组进驻了这支交付团队,开始对其进行为期4个月的敏捷改造。 在项目进展中,我们大量借鉴了源自丰田的精益思想,最终取得了显著的成效。
5S
5S是由丰田最早提出的、 用于 创造 一种 让问题变的显而易见,进而利于开展持续改进的 工作 环境的5个步骤:整理、整顿、清扫、清洁、素养。 由于这5个日文词的首字母都是S,因此统称为“5S”。 |
丰田方法的创始人大野耐一 常说 一句话 :“到现场去。” 我们坚信,一切真实的问题只能从现场发现,一切有效的改善必须从现场入手。 因此,我们没有在会议室浪费任何时间,从咨询项目启动的第一天就进驻了这支百人交付团队的工作区, 与其中一支特性组坐在一起, 尝试从现场找出问题并寻求改善。
但软件开发与制造业存在一个重要 的差异:软件开发的“ 现场 ”是不可见的。你不可能站在 这个“厂房”的中间,看到产品如何流出生产线、 什么地方堆放着在制品 。 要了解现场,必须先得到现场。 为此,必须首先对最核心的 产出物 ──代码── 进行 现场清理,使之 清晰可见。
对团队进行实地观察之后,我们发现以下问题严重阻碍了 代码的流动 :
· 代码库 中存在大量垃圾文件,尤其是 编译后的 .obj 、 .a 等中间文件被加入配置管理, 导致每次提交、合并操作都遭遇大量冲突。
· 各种脚本(包括批处理文件、ant文件、makefile等) 散落在各处,完整的构建过程没有被脚本化,开发人员构建软件的方式也各不相同。
· 团队不会使用SVN, 提交、合并操作都采用 BeyondCompare 工具手工比对差异,不仅工作量很大,而且导致SVN分支失去了版本同步信息,已经无法再进行自动的merge(合并)操作。
· 因为每次提交、合并工作量很大,团队成员普遍不敢提交代码,更害怕进行合并操作,开发者本地和项目组分支都积压了大量代码库存。
· 因为对SVN操作的恐惧,团队中已经开始流传对使用SVN、乃至对迭代开发方式的负面情绪,自动化测试脚本更是根本没有纳入SVN代码库。
为了改变这种现状,我们在这支团队中发起了一轮针对代码库的5S行动, 清理交付团队每天使用的“工作环境”,让软件生产的现场从一片混乱中显现出来。 具体的操作包括:
· 整理(Seiri ,区分有用的东西和无用的东西,将无用的东西扔掉 ) : 清理代码库中的垃圾文件, 将构建过程中生成的二进制文件全部从 配置管理 中删除 。通过整理代码库,不仅大大 降低了发生冲突的几率,而且使代码库的体积从4GB迅速降低到2GB 。
· 整顿 ( Seiton , 归置有用的东西,使其在需要时能马上用到): 全面调整工程脚本 ,将原来散落各处、用途各异的脚本贯穿起来,达到只需输入一条命令就能完成整个系统的编译、链接、打包、加载、测试、静态检查 ……简而言之,将代码变成可工作软件所需的所有步骤。 在进行整顿的过程中,我们还发现部分开发人员已经掌握了一种技巧,可以大大缩短编译时间,但这项知识没有被 分享到整个团队。通过建立标准化的构建脚本, 团队中其他开发人员也能更有效地利用这项提升效率的技巧。
· 清扫( Seiso ,净化环境,使工作顺畅): 以经过整理的 主干代码库为基准,帮助各个项目组重建工作分支, 从而彻底解决分支与主干从未合并、合并冲突极多的问题。 在重建分支的同时,对各个项目组分期分批进行操作培训, 确保团队学会使用SVN合并操作。
· 清洁( Seiketsu , 建立制度, 维持以上行动的效果): 制订 几条 简单明了的规则,确保上述 损害工作环境的情况不再出现,例如:不允许提交 .obj 文件、每天必须做一次分支与主线的合并操作,等等。 指定专人定期检查这些规则的遵守情况,发现违规操作立即 采取纠正行动。
· 素养( Shitsuke , 每位成员养成良好习惯, 持续改进 ): 起初规则的遵守需要每天专人专时来检查,随后我们又针对是否提交垃圾文件、合并主干的频率等关键问题开发了简易自动化 检查 工具,将人工检查变成自动检查,并把检查的结果摆放在醒目的位置。很快,团队就由“被迫遵守规则”转变为“自觉遵守规则”,团队成员在体会到良好工作环境的价值后开始主动 保持代码库清洁、频繁合并分支。 在5S的过程中,领导和顾问的要求逐渐变成了团队自身的习惯。
经过这轮对配置管理的5S行动, QWS团队掌握了正确使用SVN工具的方法, 一次分支合并操作的耗时从几个小时缩短到了十几分钟, 员工也打消了对SVN的恐惧感,测试人员主动将自动化测试脚本纳入了SVN代码库、与源代码统一管理。
有很多 IT企业曾经引入过5S行动。 然而令人啼笑皆非的是,这些5S行动 经常是针对程序员的办公桌来进行。 程序员真正的工作环境不在办公桌上,而在电脑“里面” :代码库、自动化脚本、软件环境,这些才是他们工作的现场。 只有发现这个现场的混乱与无序,对其进行5S,才能起到 创造良好工作环境、提升员工素养的效果。
自働化
“自働化”( jidoka ) 在丰田生产系统中专指“人性化的自动化”: 当缺陷发生时自动停止产品的流动, 以防止不合格的产品流向下一道工序和顾客 ,而不是在流程的最后进行集中检测 。 由于自働化的重点不在于“自动流动”,而在于“自动阻止流动”,它也有一个贴切的英译:auto - no - mation。 |
在启动第一迭代之前,QWS已经有一个持续集成 环境。但有趣的是,尽管持续集成环境中运行了 自动化测试,但导致持续集成失败的原因几乎总是编译问题 。一方面,测试人员经常抱怨最新版本连基本功能都运行不起来;另一方面, 自动化测试从来没有让持续集成变红过。 这样一来,持续集成就从来没有实现它“自动阻止开发流程,迫使问题 及时 解决问题”的本意,变的形同虚设。
细究之下,我们发现了其中的奥妙 :自动化测试不论成功或失败,都不会导致构建的失败。 背后的原因有两方面:首先,从技术角度,QWS使用了该公司自行研发的一个自动化测试工具 ,当在命令行调用 该工具 时,它的退出码(exit code)永远是0,即使有测试用例失败也是如此,这使得持续集成工具(C ruiseControl ) 误以为构建是成功的; 此外 , QWS的一些自动化测试用例经常 原因不明 地随机失败,使得团队认为测试完全通过是可遇而不可求的 幸事,转而关注每次构建的测试通过率。 因此只要编译通过,QWS的持续集成就一定是绿色, 团队成员会进入构建结果页面查看本次构建中有哪些用例失败。
这种看似合理的安排 实则与持续集成的本意南辕北辙。 由于缺乏直观的警示,团队就不会把解决质量问题看作最高优先级;由于默认了“随机失败”的存在, 团队就失去了对零缺陷 的追求。 只有拥有“出现质量问题时 自动停线 ” 的自働化,才能在现场、现物根据现实找到问题的根因,才能从源头上消除质量问题。
我们首先通过培训和沟通,在团队建立了这样的共识: 自働化就意味着一旦缺陷发生立即停线,作为最高优先级处理。 与意识同步的, 我们修改了执行自动化测试的ant脚本, 使其从测试工具的屏幕回显中捕捉关键字符串以判断测试是否失败,一旦有测试失败就让ant任务失败(以非0值退出命令行), 从而使持续集成构建失败。
可以想象,当我们采用这样严格的标准来要求这支团队,持续集成立即就变红了。而团队由于从前的习惯,对已经变红的持续集成浑然不觉, 仍然继续向代码库中提交新的代码,导致 失败的构建越来越难以修复。 为此,我们在项目经理例会上提出了几条纪律:
· 只允许在成功的构建基础上提交代码,构建失败或构建正在运行时不允许提交代码;
· 谁破坏构建,谁负责修复;
· 失败的构建 必须当天修复,当天不能修复则回退导致失败的提交, 将代码库 恢复到前一次成功的状态。
我们还在团队办公区的入口处摆放了一台构建监视器,将持续集成的现状 展示出来,让所有人都能看到构建是成功还是失败、谁破坏了构建。 用可视化的方式,将质量问题暴露在所有人面前, 引起整个团队的重视。
严明纪律之下, “向失败构建上继续提交代码”的情况确实被杜绝了,情况变成了“无法提交代码”: 由于自动化测试经常随机失败,构建几乎一直是红色。 这时,我们明确指出:不接受“随机失败”的说法, 一切“随机失败”背后必定有原因,只是我们还没有找到原因所在。 于是我们发起了一次“消灭伪随机问题”的活动,针对每个失败的测试用例使用“5个Why”方法追寻根因, 并找出了以下几种导致“随机失败”的原因 :
· 测试用例之间有依赖,用例执行的顺序影响结果。
· 某些用例在执行完操作后,不是等待某个结果出现, 而是等待固定的一段时间;当系统运行较慢时这些用例就会失败。
· 参与分布式构建的某些计算机本身有问题,一旦构建任务被分配到这些计算机就会失败。
找到根因之后,我们便带领一支攻关小组 逐一解决这些导致测试失败的因素,最终消灭了各种“随机失败”。
在提出严格纪律的同时,我们又为这支团队指出了避免破坏构建的方法:要想提交后构建成功,就必须在提交前用同样的标准自行检验 ,提前发现、提前解决质量问题。 在“提前验证”思想的指导下, 我们帮助各个项目组搭建了与持续集成环境相同的 本地 验证环境, 在提交代码之前先做本地验证,从而在第一时间杜绝质量问题。
经过一个多月的努力, QWS团队终于建立了一套良好的自働化机制:持续集成常绿,偶有失败的构建也能当天修复 ,测试人员每天都能得到可用的版本进行更深入的测试。
现场 管理
在丰田生产系统中,“现场”(gemba)指的是制造产品或提供服务的地方。 以大野耐一为代表的日本管理者认为,现场不仅是所有改善活动的场所,也是所有信息的来源。为了解决现场发生的大小问题, 管理阶层必须密切接触现场的实情。 |
和大多数层级森严的企业一样,QWS团队的 管理 者们 对软件开发的现场缺乏了解 ,主要通过项目经理例会的形式来听取项目经理的汇报,了解各个项目组的进度和困难。 这种通过汇报了解项目的方式存在两个重要缺陷:
· 不及时。 基层员工总是在问题相对严重时才汇报给项目经理,项目经理也总是在自己无法解决时才汇报给 版本经理,此时浪费和延迟往往已经造成。
· 不真实。 汇报的内容总是经过分析、加工和抽象的, 即便汇报人本身并没有说谎或隐瞒的意愿,但在加工的过程中就可能遗失信息,使一些风险不能被尽早识别。
要想有效改善团队的 效率,管理者们就 必须深入现场, 掌握第一手的信息, 据此提出改善方案,并监控改善的落实。 为此,我们与该 团队 负责流程改进的 人员一起, 识别出当前最需要关注的度量点, 并对这些度量点进行持续关注,以此营造一个活生生的现场。 在咨询项目进展的过程中,我们先后关注的度量点包括:
· 配置管理操作规范性 :是否原子提交?是否提交垃圾文件? 提交注释是否规范? 开发人员是否频繁提交? 分支与主干是否频繁合并?
· 持续集成纪律的遵守情况: 提交 代码 前是否先更新? 提交前是否先做本地验证? 是否在构建成功时提交? 提交后构建成功率如何?构建失败时是否及时修复?
· 项目管理工具 (JIRA) 的使用情况: 开发人员、测试人员、 需求分析人员是否及时更新JIRA? 项目经理是否使用JIRA识别 浪费和 风险?
· 团队沟通情况: 站立会议是否高效? 迭代 计划 会议是否高效?回顾会议是否高效?回顾会议得到的改善点是否落实? 团队 成员 之间的 日常 沟通是否 高效 ?
针对这些关注点,我们首先布置专人定时检查,并将检查 结果以醒目方式展示给相关 人员。 在此过程中,我们发现 有些检查属于简单重复的、能够被自动化的工作 ,于是我们又与流程改进人员一起编写了简单的自动化检查工具, 将隐藏在SVN、JIRA、 CruiseControl 等工具中的信息挖掘出来 ,清晰展现在管理者的面前,使之能够迅速掌握现场的情况,并提出改善行动。
可视化管理工具: iAnalyse 为了有效监控8个项目组、数十个构建工程的健康状态,我的同事胡凯在这个咨询项目的进展过程中,利用业余时间开发了一个持续集成状态分析工具 iAnalyse ( http://code.google.com/p/ianalyse/ ) ,于是QWS的管理者就可以每天看到各个项目组持续集成的状态了。
另一些 自动化检查 工具 不像 iAnalyse 这样有着漂亮的界面,也没有 以开源项目的形式发布出来, 但这些用半天、一天时间编写出来的小工具同样极大地简化了检查的工作,使忙碌的领导也能随时了解项目的进展情况。 |
在营造现场的过程中,我们始终贯彻两个原则。首先,现场数据要可视,用各种“信息辐射器”将项目状态展现给相关人员;另外,获取现场数据的过程要尽量不侵入团队成员的工作, 这样才能得到最真实的数据,并且将员工的抵触情绪降至最低。 在这些无侵入可视化管理手段的帮助下, QWS的各种改善措施真正落到了实处,从信息辐射器反映出的好消息又成为了员工继续改善的动力。
软件本身的不可见性使得软件项目的现场管理显得愈发困难。也正因为如此,才更需要运用各种可视化管理手段将项目的真实情况显露出来。一个明晰可视的现场不仅有利于管理者进行现场管理,也使所有项目成员能够了解项目整体情况,从每日的工作中提出改善。 《 ThoughtWorks 文集》中的“项目生命体征”一章介绍了一些需要关注的现场度量点,感兴趣的读者可以参考。
小结
经过 对“工作环境”(也就是代码配置管理库)的5S活动,建立“发生缺陷就停线”的自働化技术和管理机制,用可视化手段实施现场管理,这支原本混乱低效的大型团队已经能够稳定有序地交付可工作的软件。 但这绝非这支团队全面改善的结束,却只是个开端。在下一篇文章里,我将介绍该团队 在此基础上持续改善的步伐。