关于精益的定义有许多,但其中最令我感到鼓舞的是精益企业研究所主席 John Shooke 在它的著作《管理精益》中所描述的一段话:精益 _ 通过提高员工的水平来保证产品开发 _。在这个定义的基础上,这篇论文接下来解释了精益是怎样提高人员的水平的:方法就是解决问题。这一定义揭示了以下管理实践的美妙之处:仔细设计你的工作,让你能够清晰地看见所发生的问题(以及同时出现的学习机会),并在问题出现后以科学的方式解决。
在与使用敏捷方法进行软件开发的团队共同工作时,我曾经有过一些误解:起初时,我混淆了 bug 和问题的概念,并且确信敏捷过程就是精益,因为它能够使 bug 变得可见。在最后的几个月里,在我头脑中的概念开始渐渐清晰起来,回想起当初的情景,我开始相信,我所在的敏捷团队产生的 bug,与精益系统产生的学习机会并不是一回事:后者表明在我的团队中确实存在着质量问题,而在其它许多团队身上我也看到了同样的问题。
写这篇文章的目的,是为了描述我对 bug 与质量问题这一点上的思考方式是怎样逐渐变化的。这对于读者更好地理解造成 bug 产生的质量问题,并相应地提高绩效能够起到一些启示作用。并通过一些真实的故事描述来看清楚真正的问题所在。(先声明一点:我们并不假设所有的敏捷团队都对此问题抱有类似的误解)
什么是 bug?
在软件工业中,一个 bug 可以代表任何形式的系统错误(NullPointerException、Http 404 错误代码或是蓝屏……)、功能性错误(在我单击 B 的时候,系统本应执行 Z,却最终执行了 Y)、性能问题以及配置错误等等。
在精益的术语中,一个 bug 必须能够按照下一节提到的定义进行清晰的表达,才能说它是一个问题。请相信我,我所见过的(和自己产生的)bug 中,95% 以上都不像是某种问题——性能问题或许是个常见的例外情况,但有趣的是,它们也是绩效的一部分,不是吗?
什么是问题?
让我们在这里做一个标准的定义吧。在《丰田模式:精益模式的实践》(Toyota Way Field book)这本书中,Jeffrey Liker 定义了一个问题所需的四个方面的信息:
- 当前的实际绩效
- 预期的绩效(标准绩效或目标绩效)
- 以当前绩效和目标绩效之差所体现的问题严重程度
- 问题的范围和特点
正如 Brenée Brown 在 TED 所做的一次关于漏洞的演讲中所说的一样,如果你不能评估某个漏洞,那么它就不存在。从更实用的角度来说,如果你不能解释在绩效差距上的问题所在,那么很可能是由于你并没有花足够的时间去思考它。
在开始着手解决一个问题之前,重要的一点是要清晰地表达它,花一定时间去理解它(按照精益专家 Michael Ballé的说法:要善待它),并且克制住直奔解决方案的冲动。我们都听说过爱因斯坦的名言:“如果我只有一小时的时间去解决一个问题,我会首先用__55__ 分钟去思考问题,最后用5__ 分钟去思考解决方案。”没有人说这是件容易的事。
在软件开发敏捷团队的情境中,绩效指标或许是一张燃尽图(表示工作量与延迟)、bug 数量、系统响应时间(质量)、客户对已提交的用户故事的评价(以总分10 分来表示客户满意度),以及每个Sprint 提交的用户故事(或用户故事总点数)数量(生产力)。
按照这些指标,可以有以下这些问题存在:
质量:这个页面的响应时间目标是在500ms 以内,而在5000 个并发用户的情况下,我们测量到的结果是1500ms。
质量:在Sprint 结束时仍未解决的bug 数量(2 个,而不是0 个)
工作量/延迟:我们预计这个用户故事需要3 天时间完成,而实际上用了8 天才完成
生产力:在Sprint 结束时,整个团队共提交了5 个完成的用户故事,而之前的计划是完成7 个。
客户满意度:我们希望每个用户故事都能够得到8 分以上(满分10 分),而在上个Sprint 结束后,有两个用户故事的客户满意度低于这个分数(6.5 分和7 分)。
怎样从bug 中分析问题所在?
Bug 的出现往往是系统中产生了更常见问题的一种症状,而对于精益团队来说,将这些症状与真正的问题相关联起来是至关重要的。可以这么说,正如米开朗基罗从大理石碎片中发现它的美丽,并最终打造成迷人的雕像一样,精益团队的任务(例如某些团队会将持续改进作为他们每日工作内容的一部分)就是发挥他们的洞察力,从大量的 bug 中发现问题,并将其抽取出来。实现这一点需要进行细致地分析,并将这些原始的问题转化为学习的机会。
我发现了一种着手进行这种分析的良好方式,就是将所有 bug 分门别类,并且理解每个 bug 类别的权重。大多数情况下,某个 bug 类别就体现了造成某个现有问题的原因,或者它本身就是一个问题。这种关联性可以帮助你以正确的顺序处理这些问题,并首先从对整个操作绩效影响最大的问题开始解决。如果你仍然不确定应该从何处着手,那么优先解决质量问题是比较保险的做法。
示例 1:敏捷开发中的情景
当时我在这个使用敏捷开发的团队中担任经理一职。和许多团队一样,我们团队也不是一个跨职能的团队(典型的 Scrum-but),而是一个负责后台的团队。它在某个迭代内负责构建基础服务端软件,以便让应用团队在之后的迭代中使用这部分功能。
我们按照 Paretos 原则(即 80-20 原则)对产生的 bug 进行了一些分析,并且找出了一个占总数约 20% 的 bug 类别:这些 bug 都是由应用团队所提出的,与我们团队所建立的后台软件所暴露的 API 对“隐式”这一概念的定义有关。当应用团队在使用我们提供的功能时,经常会发生遗漏了某些输入参数,或者是缺少了某些输出数据等问题……因此他们就会为我们创建一些 bug,而我们的团队则会说:嘿!这个 API 已经隐式地表明了它不会返回这些数据。
我们同时注意到了这些 bug 的持续时间,通常从创建直到关闭为止一共持续了大约 4 个星期。(在最好的情况下)在以一个月为周期的迭代的最后阶段会进行代码发布,客户端团队则可以在下一个迭代时使用这些代码。因此当客户端团队创建了 bug,并指派给原来的开发者时,往往距离她开发那些代码时已经过去了两三个星期,开发者不得不再度拾起这段代码……
为了处理这种情况,我们决定改变一下工作的方式,将相关人员组织在一起,而产生一个相关联、跨职能并且跨技能的团队。
采用了新的方式之后,我们注意到这些“隐式 API”相关的 bug 数量大幅下降了(约 50%)。最令人欣慰的是,这种类型的 bug 的持续时间下降到了几个工作日以内。当然,这个数字有一定的水分,有些 bug 虽然被发现了,但是并没有记录下来,因为开发者们现在进行结对编程,于是许多 bug 直接在座位上就解决了。
虽然成果是显著的,但我总感觉到还有些不适之处,却说不出究竟是哪里出了问题。之后不久我才发觉,从精益的角度来说,我们目前还有两个不足之处:
- 首先,我们的系统中依然存在 bug,因此我们不得不重复劳动,这使得整个开发系统出现了生产力的浪费。但是由于缺乏内建的质量标准,我们无法保证服务端开发者所开发的 API 不存在问题。此外,对于错误的处理也没有真正的标准,我们的解决手段就是:遇到问题就坐下来一起解决。
- 尽管结果非常显著且令人振奋,但它与团队的每日绩效没并有什么直接的关联,团队也无法立即采取行动并在第二天直接看到结果。我们只是从宏观上在 6 个月结束后的发布中才能够看到这一效果:即在 bug 总数中与 API 相关的 bug 只占少数。因此我们看到:建立一个跨技能的团队确实能够在某种程度上改进质量,但我们还未能提供一种有效的方法,让我们能够每天监控它的情况,并采取相应的行动。
示例 2:精益开发中的情景
时间转眼间过去了几年,我还是任职于同一家公司中,但目前的职位是项目主管及教练,负责一个大型的多团队、多种技术的敏捷项目的实施。某一个团队遇到了一个很有挑战的技术难题,他们要与某个大家都没有什么经验的技术进行整合。整个团队在过去的两个 Sprint 中没有交付任何用户故事,他们深陷于质量问题(例如 bug)中难以自拨。当第二个 Sprint 结束后,依然没有任何完成的用户故事(比方说,按照我们对完成的定义来看,该用户故事在功能性需求上需要做到没有任何 bug)可以交付。因此在回顾会议中,整个团队一致决定,将每周进行 bug 评审(在精益中称为红箱分析)。
在第一次会议中,团队为所遇到的问题建立了一个 Pareto 模型。我们创建了一张表格,将 bug 类别放在一列里,bug 的数量和 bug ID 则分别用余下的几列来表示。
之后的目标是逐个排除每种 bug 类别背后的根本问题,首先从发生次数最频繁的开始。为了鼓励团队成员就这一话题展开交流,Scrum Master 决定将这张 Pareto 表格贴在 Scrum 公告板与 bug 数量的旁边,并且每天对其进行更新。在每天早上的站立会议上,团队都会报告当前的 bug 情况,而新产生的 bug 都会按照其分类添加到该表格中。这种方式能够使团队更明显地意识到每日质量性能的变化情况,同时也是实现 PDCA 中的 C——Check(检验)的一种良好方式。当问题被根除之后,这方面的 bug 应该至少在一周之内不复存在了。不过,某些时候还是会发生这些 bug,而这也是需要学习的地方。
举一个例子,该团队已经认识到了 bug 类别中有一种属于回归缺陷,即对软件的改动破坏了原本能够正常工作的特性。这种 bug 多数情况下发生在图形用户界面端,因为对这一部分进行自动化测试是非常困难的事。我们所找出的一个根本问题在于,初级程序员并不总是完全理解他们对代码的改动可能会造成的影响。对此问题的解决措施是在流程中加入一个新的步骤,在提交代码之前先让某个更资深的开发者进行代码复审。这一步骤大概只需要 15 分钟,但能够大幅降低回归缺陷出现的次数。此外还将对每次发布的 bug 数量进行每日评估(每天发布两次)。这种方式还能够提高初级开发者的技能水平。
最终,所有的问题都得到了解决,结果是令人惊叹的:所有的问题都通过标准流程(在提交代码之前进行代码复审)得以一一根除。每日的 bug 数量直线下降,每个迭代周末能够提交的包括完整功能并且无 bug 的用户故事数量也在上升。3 个月之后,该团队就从之前产生 bug 数量最多的困境中摇身一变,成为了整个项目中高质量、高效率团队的代名词。
这种方式相比之前的方法显得更为精益。因为它对每日绩效(质量)和生产力(提交的用户故事数量)产生了直接的影响,并且为团队带来了新的操作标准。
图2:敏捷团队的性能指标示例
将一个敏捷团队转变为学习团队
经历过了以上两个示例之后,加上我从这次经历中所学到的经验,我将为你推荐一种将敏捷团队转变为精益和学习团队的路线图:
- 对绩效进行评估,让它可为众人所见,并且每天都要对它展开讨论。 我能够理解这一点对于某些非主流的敏捷教练来说是难以忍受的,但事实可能会令你感到沮丧:如果我们需要进行改进,那么首先要做的第一件事就是评估。此外,最重要的一点是,只有面对现实,才能进行深刻的学习。网络巨擎(谷歌、亚马逊、Twitter 及 Facebook)或者实践领导者(Etsy)都是这样做的:他们对每件事情都进行评估,如果他们仅仅关注于计算用户故事的点数,就不可能达到如今的绩效。在敏捷团队方面有个实际的例子可供参考:除了 Sprint 燃尽图之外,还要展示质量绩效(没有关闭的 bug 数量、每次发布的 bug 数量、每种类别的 bug 数量,等等)、客户满意度(例如对交付的用户故事按照总分 10 分进行评分),并且每一天都对燃尽图没有达到预期目标的原因进行分析。
- 确保使用精益的方式表达问题 对于某个问题的表达必须包含两个方面:所观察到的绩效和目标绩效。Pareto 是一种将原始的 bug 进行分类处理的优秀工具,但还要专门进行分析,以理解每个类别是如何影响到绩效的。
- 这种方式可以保证你已经清晰地为划分了问题的类型,并且从商业绩效的角度以正确的次序分别进行处理。
- 当问题出现时逐一分析解决 精益式解决问题方法的关键之一,就在于不要试图同时解决多个问题。你只需要专注于一个问题,理解它如何影响你的绩效指标,并确保你理解造成该问题的原因所在。
- 进行校验 很遗憾,根据我的经验来看,我们通常会倾向于忽略这一步骤。如果你的预估与现实不符、你的软件不能正常工作,那很好!你是否可以从中学到些什么?如果你所想象中会发生的事与实际发生的事产生了偏差,那这一段偏差就是可以从中进行学习的地方。这正是在第二个示例中的团队所做的事。正如 Stephen J. Spear 在他的著作《 Chasing the Rabbit 》中所写的一样,这是你的组织中的系统在向你发出的一种声音:“在我身上还有一些你所不了解的东西,但如果你愿意倾听,我就会告诉你。”团队正是这样才能够从工作与流程中快速地培养自己的专业技能,并真正地成为一支梦想中的团队。
从敏捷到精益
我从 2004 年开始成为一名敏捷实践者,而在过去的几年中,我的思维方式渐渐转为精益。正是它帮助我跨越了一些单纯依靠敏捷无法跨过的障碍。
按我的经验来看,精益已经被证明是一种有效的手段,它能够帮助你超越敏捷,建立起一种持续改进的实践,并为团队带来直接的绩效提高和激励作用。而明确地区分 bug 与问题这一方式已经被证实是对持续改进的一大助力。
如果你也开始了这一相同的过程,你是否能指出 bug 与问题之间有哪些关键的区别因素吗?
关于作者
Cecil Dijoux在 Operae Partners 担任精益 IT 教练,他是一位具有 25 年国际经验的 IT 专家。 他对探索 21 世纪的管理方式(精益、敏捷、Enterprise 2.0 等等)充满热情。Cecil 在他的博客 http://thehypertextual.com/ 中写了大量有关于互联世界中的组织文化方面的文章,有法语和英语两个版本。纽约时报在线和 Read Write Enterprise 曾经专门报道过他的一篇博客文章。Cecil 还是一位国际性的演讲者,并且还是一份法语电子书“#hyperchange - petit guide de la conduite du changement dans l’économie de la connaissance”的作者,书中主要描写了关于知识经济时代的管理方式的变化。
评论