
示例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與問題之間有哪些關鍵的區別因素嗎?