為什么企業(yè)要做大規(guī)模敏捷?
作者 | 曾雪松
背景
軟件工程里一個重要的指標就是“可用的軟件”,敏捷宣言里也同樣告訴我們“工作的軟件高于詳盡的文檔”,那“可用的軟件”、“工作的軟件”意味著什么呢?在我的理解里,可以經(jīng)歷用戶 “千錘百煉”的軟件就是一個“可用的軟件”。曾經(jīng)聽到過這樣的說法:“一個有Bug的軟件怎么能叫軟件呢?”雖然這話在我們業(yè)內人士聽起來有些可笑,但是這就是使用軟件用戶最真實的需求。所以如何在提高代碼質量,最大程度地減少軟件中的Bug同時,平衡軟件迭代速度與交付效率是我今天想跟大家討論的問題。
我有幸在兩種完全不同風格的項目上進行過交付,讓我們且稱之為項目A和項目B。
項目A是一個客戶為主導的巨大項目組,管理為明確縱向層級管理,橫向開發(fā)團隊來自于不同的供應商,并且采用瀑布式開發(fā),由另一個事業(yè)部進行測試反饋,部門墻極其嚴重。
項目B則是一個由業(yè)務主導,每個敏捷團隊有對應相關的業(yè)務領域,客戶則是和供應商共同組成一個個敏捷團隊,共同達成業(yè)務目標。
好了,完成了簡單的背景介紹,我就要來說說下面的故事了。
故事
總覽
首先,假設我們所需要達到的目標是由一個個大大小小功能(顏色模組)組成一個完整的軟件,為了達到我們的交付目標,我們需要將每個功能進行開發(fā),測試,將功能模塊進行累加,最終獲得一個完整而達標的軟件。
同時兩個項目都使用了大致相同的開發(fā)流程,為了保證質量,項目中都有基礎的代碼審計,CI/CD,應用測試,用戶測試,等基本質量保證,軟件開發(fā)的基礎流程如下圖:
在這種基礎流程都相近的情況下,每個環(huán)節(jié)在不同架構下執(zhí)行的的方式卻有巨大的差異。
在討論項目A的流程前,讓我們先看看我們熟知的敏捷開發(fā)是怎么保證質量的:
項目B的情況
項目b的每一個小敏捷團隊將業(yè)務需求從路徑圖(Roadmap)拆解下來,落到各大的業(yè)務功能的Epic中,再拆解成具有小的業(yè)務價值的用戶故事,最后再落到每個具有開發(fā)意義的任務,注意,這里提的一直是業(yè)務價值,我們還沒有開始討論如何進入開發(fā)。
Epic 更多是獨立且較大的目標,用于我們識別在關鍵時間點需要實現(xiàn)的大型業(yè)務目標。而用戶故事則是一個簡短的描述、一個用于表達用戶或客戶的需求的角色和一個用于描述需求的價值或期望結果的價值陳述,在用戶故事中比較關鍵描述是關于此價值點的“靜態(tài)““動態(tài)”與“非常態(tài)“,靜態(tài)更多的是對價值點的描述,在To C中往往是靜態(tài)設計圖(UI)的描述,動態(tài)則是交互,系統(tǒng)間的交互或者功能的用戶旅程(UX),而非常態(tài)則是描述系統(tǒng)在錯誤或者誤差情況下的表現(xiàn),以確保當前的價值點在絕大多數(shù)情況下得以運行(AC)。最終用戶故事將被團隊中的技術領導拆解成可以單獨執(zhí)行的開發(fā)任務,最終沒個獨立的開發(fā)任務可以由不同的開發(fā)人員執(zhí)行。
在一個大型的價值目標被拆解成了Epic->用戶故事->開發(fā)任務的過程中需要全團隊的多輪確認,多輪確認確保所有人達成統(tǒng)一共識 ,在最大的程度上解決溝通差帶來的不確定性。最終需要通過迭代計劃會議在團隊內部對價值達成共識后,才會進行項目開發(fā)。
進入開發(fā)任務后每個階段,參考下圖:
我們可以看到4重質量保證:
- 結對編程:兩個人的腦子總比一個人想的全。(其他好處不用贅述)
- 團隊中的代碼版本差異識別:每對Pair的代碼在一天結束時會被整個開發(fā)團隊審核(當然可以提高代碼質量了)
- 代碼審計:當對應開發(fā)任務 - PR(每筆代碼)完成后,會被整個團隊提意見(我聽過比較離譜的就是:Our PR is waiting for more comments),修正完成后代碼才會進入測試階段。
- 測試: 最后的最后,才會進行測試,整個測試則是由小團隊內部完成,在沒有測試的情況下,“非常態(tài)”的AC就是整個測試的通過條件。
再這樣一輪一輪的開發(fā)任務到用戶故事的價值交付后,又組成了一個Epic價值交付,最終通過Bug Bash的方式最后確認價值以達到交付標準,我們可以上線整個Epic用于用戶的檢驗。
總結一下敏捷開發(fā)的特點:
- 業(yè)務 -> 開發(fā) -> 測試由一個全職能敏捷團隊完成
- 大多數(shù)內容由團隊內部確定
- 由上向下“順時針“開發(fā)
- 盡可能的小型功能,快速迭代
- 小型逆時針回調細節(jié)確認
- 業(yè)務導向:業(yè)務決定質量
用圖來表示最終內建的結果,在最終快要上線時,經(jīng)過團隊內質量把控后僅與實際有極少差距,僅需要在日常使用中進行基礎運維即可達到我們的價值目標:
項目A的情況
這時候讓我們再來看項目A,系統(tǒng)被產(chǎn)品部門完成設計后,交予開發(fā)部門進行任務劃分,每個開發(fā)團隊承擔不同的功能開發(fā)任務,每個功能點再由單獨開發(fā)人員進行開發(fā)并自行測試(本地),最后由客戶方進行功能驗收后(功能展示+代碼審核),代碼合入主線進行轉測。
說到這兒,舉個例子,產(chǎn)品部門提供了本次需要交付的20個功能的設計圖,開發(fā)團隊把設計圖分給交付團隊(大多由供應商組成),團隊成員小王負責對其中一張設計圖(類似于一個Epic)的功能進行開發(fā),開發(fā)完成后開驗收會議,對代碼和功能進行審核驗證,進入測試流程。所以開發(fā)階段歸納下來的話,如圖:
這樣乍一看確實沒有什么問題,開發(fā)流程中的各種實踐也在做,那這種項目研發(fā)模式問題出在哪兒呢?這個時候我們看項目A的關鍵質量保證動作:測試。
項目A的測試步驟:
先拋結論,在測試階段,80%時間用于確定問題+定位問題(標紅)。所以我們可以著重討論一下這兩個階段。
確認問題:在確認問題階段, 往往由測試組發(fā)起,通過層層追溯,可以追溯到開發(fā)人員(也就是小王),跟小王確認表現(xiàn)層的“靜態(tài)”/“動態(tài)”/“非常態(tài)”問題后,測試順利成章地建立一個問題工單,并分配給小王,宣告此單插在了小王頭上,小王需要修正再找測試回歸。乍一看又沒什么問題,是個好流程,但是執(zhí)行起來此流程會出現(xiàn):
- 因為測試標準中有較多主觀的感官感受,導致在跟開發(fā)確認問題時經(jīng)常出現(xiàn)主觀問題,此時需要產(chǎn)品介入,并用主觀感受進行判定。(缺少用戶旅程細節(jié))
舉例:(一個電話拉會)“小王,我覺得這個頁面幀數(shù)好低,你要優(yōu)化一下?!薄鞍????”(此處省略battle的10分鐘)終于電話給了產(chǎn)品,產(chǎn)品一句話:“是幀數(shù)有點低??!小王,這你得改”“…”
- 需要產(chǎn)品介入的場景往往流程會變得極長。測試在做測試中,會考慮很多“非常態(tài)“問題,在非常態(tài)問題中,往往會導致”靜態(tài)“”動態(tài)“的變更,然后經(jīng)過工單追蹤,產(chǎn)品組漫長的重新設計,然后再由開發(fā)進行更改。
- 當存在“扯皮”問題,又是另外一副光景。
舉例:測試打電話給小王,小王說“這不是我的問題,你找xx團隊的小李 ”,小李接上電話,“這是你小王開發(fā)的啊”..(再次省略battle時間)最終問題很有可能上升到客戶方確定問題邊界,這樣1個小時就過去了。
- 開發(fā)的專注思考時間被切碎。在轉測后,需要大量地確認問題,也就是跟測試打電話,測試往往是發(fā)現(xiàn)問題第一時間就會確認問題,這樣導致開發(fā)人員每天專注于代碼工作的時間被切碎,效率直接下降。
定位問題: 定位問題同樣占據(jù)了開發(fā)人員的大量時間,總體來說:
- 大量追溯代碼:確認問題后,有時會需要確定整個功能代碼中的問題點,問題很難定位,尤其遇到比較棘手的概率,性能問題需要對整個代碼進行回顧與重構。
- 涉及他方代碼:當在長時間確認問題后,問題有時會涉及他人代碼,比如框架代碼,他人功能代碼,硬件代碼,這時候需要你找到相關人(打電話),解釋,最終把工單走到他人名下(當然沒人愿意接單,長時間Battle在所難免)。
- 定位到無法修改的問題:當然在這里又有專門的流程做這件事,問題就出現(xiàn)在因為團隊間的互相的部門/信任墻,需要長流程(COC:需求變更會議)來共同確認問題,需要引入大量具有決策權的角色:另外團隊的架構師,產(chǎn)品經(jīng)理,測試經(jīng)理,還有可憐的小王。最終一個無法修改的工單往往需要2周或者更多的時間進行關閉。
- 流程反復:當出現(xiàn) 確認問題->定位問題->確認問題->定位問題…這個如此反復的流程時,對開發(fā)和測試的神經(jīng)都是一個極大的考驗。
后續(xù)的修改流程往往較為順利,但是也會出現(xiàn)一個工單反復無法通過回歸的問題,這畢竟是少數(shù),也不是我們主要探討的范疇。項目在強流程驅動下最終的結果就是:
所有人每天都在加班,所有人每天都在增加流程以確保質量,所有人都很痛苦,當然這里包括小王。
用圖來表示開發(fā)結束后的狀態(tài),空隙區(qū)域代表不確定問題,空隙部分需要測試->開發(fā)->產(chǎn)品逆流程更改
總結
說了這么多細節(jié),我想現(xiàn)在跳出來問“為什么會出現(xiàn)這樣的問題?”這個問題我也想留個大家做一點思考,我做了一些簡單而又主觀的總結,放在這里:
- 共識缺失:當大家都在自己的職能部門做自己的工作時,往往會主觀地做這件事兒,當這件事兒在后續(xù)流轉時,沒有通過一個整體共識的話,往往需要從底端流程不斷向上確認達成共識。
- 大規(guī)模“逆時針”回調:因為整體共識由測試發(fā)起,加上部門墻重,往往導致從測試->開發(fā)->產(chǎn)品的逆時針開發(fā)流程,代碼重構與返工的工作量極大。
- 價值產(chǎn)出慢:當最終功能在大量回調時,價值產(chǎn)出很慢,導致驗證慢,最終導致逆向反饋增加。
- 流程決定質量:還是由測試流程來確定質量的情況下,在產(chǎn)品只進行Happy Pass的情況下,所有人的彌合質量的成本都在成倍增加。
看完了項目A和項目B的整體, 我們最后再來聊聊效率,我們發(fā)現(xiàn),在同等的質量要求下,敏捷效率反而高很多,在流程更短的情況下卻交付出了同樣質量很高的產(chǎn)品,最后我們通過對比總結一下,為什么敏捷在保證質量的同時還能有更高的效率?
我們暫且停在這兒,我要引用SAFe中的一張圖來結束我今天的闡述,也在用實例回答:“為什么企業(yè)要做大規(guī)模敏捷?”
我想答案是:質量高,效率快,大家都開心。