背景
軟件工程里一個(gè)重要的指標(biāo)就是“可用的軟件”煎源,敏捷宣言里也同樣告訴我們“工作的軟件高于詳盡的文檔”,那“可用的軟件”手销、“工作的軟件”意味著什么呢?在我的理解里诈悍,可以經(jīng)歷用戶 “千錘百煉”的軟件就是一個(gè)“可用的軟件”。曾經(jīng)聽到過這樣的說法:“一個(gè)有Bug的軟件怎么能叫軟件呢兽埃?”雖然這話在我們業(yè)內(nèi)人士聽起來有些可笑写隶,但是這就是使用軟件用戶最真實(shí)的需求。所以如何在提高代碼質(zhì)量讲仰,最大程度地減少軟件中的Bug同時(shí),平衡軟件迭代速度與交付效率是我今天想跟大家討論的問題痪蝇。
我有幸在兩種完全不同風(fēng)格的項(xiàng)目上進(jìn)行過交付鄙陡,讓我們且稱之為項(xiàng)目A和項(xiàng)目B。
項(xiàng)目A是一個(gè)客戶為主導(dǎo)的巨大項(xiàng)目組躏啰,管理為明確縱向?qū)蛹?jí)管理趁矾,橫向開發(fā)團(tuán)隊(duì)來自于不同的供應(yīng)商,并且采用瀑布式開發(fā)给僵,由另一個(gè)事業(yè)部進(jìn)行測(cè)試反饋毫捣,部門墻極其嚴(yán)重详拙。
項(xiàng)目B則是一個(gè)由業(yè)務(wù)主導(dǎo),每個(gè)敏捷團(tuán)隊(duì)有對(duì)應(yīng)相關(guān)的業(yè)務(wù)領(lǐng)域蔓同,客戶則是和供應(yīng)商共同組成一個(gè)個(gè)敏捷團(tuán)隊(duì)饶辙,共同達(dá)成業(yè)務(wù)目標(biāo)。
好了斑粱,完成了簡(jiǎn)單的背景介紹弃揽,我就要來說說下面的故事了。
故事
總覽
首先则北,假設(shè)我們所需要達(dá)到的目標(biāo)是由一個(gè)個(gè)大大小小功能(顏色模組)組成一個(gè)完整的軟件矿微,為了達(dá)到我們的交付目標(biāo),我們需要將每個(gè)功能進(jìn)行開發(fā)尚揣,測(cè)試涌矢,將功能模塊進(jìn)行累加,最終獲得一個(gè)完整而達(dá)標(biāo)的軟件快骗。
同時(shí)兩個(gè)項(xiàng)目都使用了大致相同的開發(fā)流程,為了保證質(zhì)量思灌,項(xiàng)目中都有基礎(chǔ)的代碼審計(jì)泰偿,CI/CD耗跛,應(yīng)用測(cè)試调塌,用戶測(cè)試羔砾,等基本質(zhì)量保證姜凄,軟件開發(fā)的基礎(chǔ)流程如下圖态秧。
在這種基礎(chǔ)流程都相近的情況下申鱼,每個(gè)環(huán)節(jié)在不同架構(gòu)下執(zhí)行的的方式卻有巨大的差異。
在討論項(xiàng)目A的流程前淫半,讓我們先看看我們熟知的敏捷開發(fā)是怎么保證質(zhì)量的:
項(xiàng)目B的情況
項(xiàng)目b的每一個(gè)小敏捷團(tuán)隊(duì)將業(yè)務(wù)需求從路徑圖(Roadmap)拆解下來撮慨,落到各大的業(yè)務(wù)功能的Epic中砌溺,再拆解成具有小的業(yè)務(wù)價(jià)值的用戶故事变隔,最后再落到每個(gè)具有開發(fā)意義的任務(wù)匣缘,注意肌厨,這里提的一直是業(yè)務(wù)價(jià)值柑爸,我們還沒有開始討論如何進(jìn)入開發(fā)。
Epic 更多是獨(dú)立且較大的目標(biāo)馅而,用于我們識(shí)別在關(guān)鍵時(shí)間點(diǎn)需要實(shí)現(xiàn)的大型業(yè)務(wù)目標(biāo)瓮恭。而用戶故事則是一個(gè)簡(jiǎn)短的描述屯蹦、一個(gè)用于表達(dá)用戶或客戶的需求的角色和一個(gè)用于描述需求的價(jià)值或期望結(jié)果的價(jià)值陳述颇玷,在用戶故事中比較關(guān)鍵描述是關(guān)于此價(jià)值點(diǎn)的“靜態(tài)““動(dòng)態(tài)”與“非常態(tài)“,靜態(tài)更多的是對(duì)價(jià)值點(diǎn)的描述竭宰,在To C中往往是靜態(tài)設(shè)計(jì)圖(UI)的描述,動(dòng)態(tài)則是交互狞甚,系統(tǒng)間的交互或者功能的用戶旅程(UX)哼审,而非常態(tài)則是描述系統(tǒng)在錯(cuò)誤或者誤差情況下的表現(xiàn)涩盾,以確保當(dāng)前的價(jià)值點(diǎn)在絕大多數(shù)情況下得以運(yùn)行(AC)春霍。最終用戶故事將被團(tuán)隊(duì)中的技術(shù)領(lǐng)導(dǎo)拆解成可以單獨(dú)執(zhí)行的開發(fā)任務(wù)址儒,最終沒個(gè)獨(dú)立的開發(fā)任務(wù)可以由不同的開發(fā)人員執(zhí)行莲趣。
在一個(gè)大型的價(jià)值目標(biāo)被拆解成了Epic->用戶故事->開發(fā)任務(wù)的過程中需要全團(tuán)隊(duì)的多輪確認(rèn)喧伞,多輪確認(rèn)確保所有人達(dá)成統(tǒng)一共識(shí) 理朋,在最大的程度上解決溝通差帶來的不確定性嗽上。最終需要通過迭代計(jì)劃會(huì)議在團(tuán)隊(duì)內(nèi)部對(duì)價(jià)值達(dá)成共識(shí)后兽愤,才會(huì)進(jìn)行項(xiàng)目開發(fā)浅萧。
進(jìn)入開發(fā)任務(wù)后每個(gè)階段吩案,參考下圖:
我們可以看到4重質(zhì)量保證:
- 結(jié)對(duì)編程:兩個(gè)人的腦子總比一個(gè)人想的全徘郭。(其他好處不用贅述)
- 團(tuán)隊(duì)中的代碼版本差異識(shí)別:每對(duì)Pair的代碼在一天結(jié)束時(shí)會(huì)被整個(gè)開發(fā)團(tuán)隊(duì)審核(當(dāng)然可以提高代碼質(zhì)量了)
- 代碼審計(jì):當(dāng)對(duì)應(yīng)開發(fā)任務(wù) - PR(每筆代碼)完成后,會(huì)被整個(gè)團(tuán)隊(duì)提意見(我聽過比較離譜的就是:Our PR is waiting for more comments),修正完成后代碼才會(huì)進(jìn)入測(cè)試階段胧后。
- 測(cè)試: 最后的最后壳快,才會(huì)進(jìn)行測(cè)試眶痰,整個(gè)測(cè)試則是由小團(tuán)隊(duì)內(nèi)部完成凛驮,在沒有測(cè)試的情況下黔夭,“非常態(tài)”的AC就是整個(gè)測(cè)試的通過條件本姥。
再這樣一輪一輪的開發(fā)任務(wù)到用戶故事的價(jià)值交付后婚惫,又組成了一個(gè)Epic價(jià)值交付先舷,最終通過Bug Bash的方式最后確認(rèn)價(jià)值以達(dá)到交付標(biāo)準(zhǔn)蒋川,我們可以上線整個(gè)Epic用于用戶的檢驗(yàn)捺球。
總結(jié)一下敏捷開發(fā)的特點(diǎn):
- 業(yè)務(wù) -> 開發(fā) -> 測(cè)試由一個(gè)全職能敏捷團(tuán)隊(duì)完成
- 大多數(shù)內(nèi)容由團(tuán)隊(duì)內(nèi)部確定
- 由上向下“順時(shí)針“開發(fā)
- 盡可能的小型功能氮兵,快速迭代
- 小型逆時(shí)針回調(diào)細(xì)節(jié)確認(rèn)
- 業(yè)務(wù)導(dǎo)向:業(yè)務(wù)決定質(zhì)量
用圖來表示最終內(nèi)建的結(jié)果泣栈,在最終快要上線時(shí)南片,經(jīng)過團(tuán)隊(duì)內(nèi)質(zhì)量把控后僅與實(shí)際有極少差距铃绒,僅需要在日常使用中進(jìn)行基礎(chǔ)運(yùn)維即可達(dá)到我們的價(jià)值目標(biāo):
項(xiàng)目A的情況
這時(shí)候讓我們?cè)賮砜错?xiàng)目A颠悬,系統(tǒng)被產(chǎn)品部門完成設(shè)計(jì)后赔癌,交予開發(fā)部門進(jìn)行任務(wù)劃分灾票,每個(gè)開發(fā)團(tuán)隊(duì)承擔(dān)不同的功能開發(fā)任務(wù)刊苍,每個(gè)功能點(diǎn)再由單獨(dú)開發(fā)人員進(jìn)行開發(fā)并自行測(cè)試(本地)正什,最后由客戶方進(jìn)行功能驗(yàn)收后(功能展示+代碼審核)婴氮,代碼合入主線進(jìn)行轉(zhuǎn)測(cè)主经。
說到這兒罩驻,舉個(gè)例子鉴腻,產(chǎn)品部門提供了本次需要交付的20個(gè)功能的設(shè)計(jì)圖爽哎,開發(fā)團(tuán)隊(duì)把設(shè)計(jì)圖分給交付團(tuán)隊(duì)(大多由供應(yīng)商組成)课锌,團(tuán)隊(duì)成員小王負(fù)責(zé)對(duì)其中一張?jiān)O(shè)計(jì)圖(類似于一個(gè)Epic)的功能進(jìn)行開發(fā)渺贤,開發(fā)完成后開驗(yàn)收會(huì)議志鞍,對(duì)代碼和功能進(jìn)行審核驗(yàn)證固棚,進(jìn)入測(cè)試流程此洲。所以開發(fā)階段歸納下來的話呜师,如圖
這樣乍一看確實(shí)沒有什么問題汁汗,開發(fā)流程中的各種實(shí)踐也在做碰酝,那這種項(xiàng)目研發(fā)模式問題出在哪兒呢送爸?這個(gè)時(shí)候我們看項(xiàng)目A的關(guān)鍵質(zhì)量保證動(dòng)作:測(cè)試袭厂。
項(xiàng)目A的測(cè)試步驟:
先拋結(jié)論纹磺,在測(cè)試階段橄杨,80%時(shí)間用于確定問題+定位問題(標(biāo)紅)。所以我們可以著重討論一下這兩個(gè)階段乡摹。
確認(rèn)問題:在確認(rèn)問題階段聪廉, 往往由測(cè)試組發(fā)起板熊,通過層層追溯,可以追溯到開發(fā)人員(也就是小王)津辩,跟小王確認(rèn)表現(xiàn)層的“靜態(tài)”/“動(dòng)態(tài)”/“非常態(tài)”問題后丹泉,測(cè)試順利成章地建立一個(gè)問題工單鸭蛙,并分配給小王娶视,宣告此單插在了小王頭上肪获,小王需要修正再找測(cè)試回歸孝赫。乍一看又沒什么問題青柄,是個(gè)好流程致开,但是執(zhí)行起來此流程會(huì)出現(xiàn):
-
因?yàn)闇y(cè)試標(biāo)準(zhǔn)中有較多主觀的感官感受双戳,導(dǎo)致在跟開發(fā)確認(rèn)問題時(shí)經(jīng)常出現(xiàn)主觀問題飒货,此時(shí)需要產(chǎn)品介入塘辅,并用主觀感受進(jìn)行判定邪驮。(缺少用戶旅程細(xì)節(jié))
舉例:(一個(gè)電話拉會(huì))“小王,我覺得這個(gè)頁面幀數(shù)好低盘榨,你要優(yōu)化一下草巡∩胶”“坝艟埂棚亩?讥蟆?瘸彤?”(此處省略battle的10分鐘)終于電話給了產(chǎn)品笛钝,產(chǎn)品一句話:“是幀數(shù)有點(diǎn)低安C摇啃奴!小王,這你得改”“…”
需要產(chǎn)品介入的場(chǎng)景往往流程會(huì)變得極長(zhǎng)依溯。測(cè)試在做測(cè)試中黎炉,會(huì)考慮很多“非常態(tài)“問題慷嗜,在非常態(tài)問題中庆械,往往會(huì)導(dǎo)致”靜態(tài)“”動(dòng)態(tài)“的變更,然后經(jīng)過工單追蹤沐序,產(chǎn)品組漫長(zhǎng)的重新設(shè)計(jì),然后再由開發(fā)進(jìn)行更改奴紧。
-
當(dāng)存在“扯皮”問題黍氮,又是另外一副光景滤钱。
舉例:測(cè)試打電話給小王件缸,小王說“這不是我的問題他炊,你找xx團(tuán)隊(duì)的小李 ”,小李接上電話凿叠,“這是你小王開發(fā)的啊”..(再次省略battle時(shí)間)最終問題很有可能上升到客戶方確定問題邊界嚼吞,這樣1個(gè)小時(shí)就過去了舱禽。
開發(fā)的專注思考時(shí)間被切碎誊稚。在轉(zhuǎn)測(cè)后,需要大量地確認(rèn)問題城瞎,也就是跟測(cè)試打電話渤闷,測(cè)試往往是發(fā)現(xiàn)問題第一時(shí)間就會(huì)確認(rèn)問題,這樣導(dǎo)致開發(fā)人員每天專注于代碼工作的時(shí)間被切碎全谤,效率直接下降肤晓。
定位問題: 定位問題同樣占據(jù)了開發(fā)人員的大量時(shí)間,總體來說:
- 大量追溯代碼:確認(rèn)問題后认然,有時(shí)會(huì)需要確定整個(gè)功能代碼中的問題點(diǎn)补憾,問題很難定位,尤其遇到比較棘手的概率卷员,性能問題需要對(duì)整個(gè)代碼進(jìn)行回顧與重構(gòu)盈匾。
- 涉及他方代碼:當(dāng)在長(zhǎng)時(shí)間確認(rèn)問題后未巫,問題有時(shí)會(huì)涉及他人代碼,比如框架代碼跛璧,他人功能代碼,硬件代碼抬吟,這時(shí)候需要你找到相關(guān)人(打電話)缺亮,解釋惭蹂,最終把工單走到他人名下(當(dāng)然沒人愿意接單,長(zhǎng)時(shí)間Battle在所難免)耗美。
- 定位到無法修改的問題:當(dāng)然在這里又有專門的流程做這件事芥玉,問題就出現(xiàn)在因?yàn)閳F(tuán)隊(duì)間的互相的部門/信任墻,需要長(zhǎng)流程(COC:需求變更會(huì)議)來共同確認(rèn)問題,需要引入大量具有決策權(quán)的角色:另外團(tuán)隊(duì)的架構(gòu)師,產(chǎn)品經(jīng)理,測(cè)試經(jīng)理,還有可憐的小王玄妈。最終一個(gè)無法修改的工單往往需要2周或者更多的時(shí)間進(jìn)行關(guān)閉枯饿。
- 流程反復(fù):當(dāng)出現(xiàn) 確認(rèn)問題->定位問題->確認(rèn)問題->定位問題…這個(gè)如此反復(fù)的流程時(shí)爸舒,對(duì)開發(fā)和測(cè)試的神經(jīng)都是一個(gè)極大的考驗(yàn)苛聘。
后續(xù)的修改流程往往較為順利,但是也會(huì)出現(xiàn)一個(gè)工單反復(fù)無法通過回歸的問題,這畢竟是少數(shù),也不是我們主要探討的范疇。項(xiàng)目在強(qiáng)流程驅(qū)動(dòng)下最終的結(jié)果就是:
所有人每天都在加班重贺,所有人每天都在增加流程以確保質(zhì)量潜圃,所有人都很痛苦吧凉,當(dāng)然這里包括小王。
用圖來表示開發(fā)結(jié)束后的狀態(tài)赏廓,空隙區(qū)域代表不確定問題既忆,空隙部分需要測(cè)試->開發(fā)->產(chǎn)品逆流程更改
總結(jié)
說了這么多細(xì)節(jié),我想現(xiàn)在跳出來問“為什么會(huì)出現(xiàn)這樣的問題?”這個(gè)問題我也想留個(gè)大家做一點(diǎn)思考庐舟,我做了一些簡(jiǎn)單而又主觀的總結(jié),放在這里:
- 共識(shí)缺失:當(dāng)大家都在自己的職能部門做自己的工作時(shí)摊求,往往會(huì)主觀地做這件事兒,當(dāng)這件事兒在后續(xù)流轉(zhuǎn)時(shí),沒有通過一個(gè)整體共識(shí)的話埃脏,往往需要從底端流程不斷向上確認(rèn)達(dá)成共識(shí)。
- 大規(guī)模“逆時(shí)針”回調(diào):因?yàn)檎w共識(shí)由測(cè)試發(fā)起佩迟,加上部門墻重厨钻,往往導(dǎo)致從測(cè)試->開發(fā)->產(chǎn)品的逆時(shí)針開發(fā)流程诱建,代碼重構(gòu)與返工的工作量極大。
- 價(jià)值產(chǎn)出慢:當(dāng)最終功能在大量回調(diào)時(shí),價(jià)值產(chǎn)出很慢驱敲,導(dǎo)致驗(yàn)證慢我碟,最終導(dǎo)致逆向反饋增加。
- 流程決定質(zhì)量:還是由測(cè)試流程來確定質(zhì)量的情況下包斑,在產(chǎn)品只進(jìn)行Happy Pass的情況下元镀,所有人的彌合質(zhì)量的成本都在成倍增加蔽挠。
看完了項(xiàng)目A和項(xiàng)目B的整體, 我們最后再來聊聊效率,我們發(fā)現(xiàn)冬殃,在同等的質(zhì)量要求下官册,敏捷效率反而高很多满粗,在流程更短的情況下卻交付出了同樣質(zhì)量很高的產(chǎn)品步淹,最后我們通過對(duì)比總結(jié)一下辛燥,為什么敏捷在保證質(zhì)量的同時(shí)還能有更高的效率内边?
| 敏捷團(tuán)隊(duì) | 職能團(tuán)隊(duì) |
| 業(yè)務(wù)決定質(zhì)量 | 流程決定質(zhì)量 |
| 回調(diào)(重構(gòu))路徑短 | 回調(diào)(重構(gòu))路徑長(zhǎng) |
| 快速產(chǎn)出價(jià)值并驗(yàn)證價(jià)值 | 慢速產(chǎn)出價(jià)值驗(yàn)證價(jià)值慢 |
| 團(tuán)隊(duì)成員共同決策->快速達(dá)成共識(shí) | 單一角色決策->長(zhǎng)流程確認(rèn)共識(shí) |
| 專注手頭工作 | 分散精力處理流程 |
| 團(tuán)隊(duì)凝聚力強(qiáng) | 職能部門間不信任 |
| 開心 | 痛苦 |
我們暫且停在這兒莹汤,我要引用SAFe中的一張圖來結(jié)束我今天的闡述,也在用實(shí)例回答:“為什么企業(yè)要做大規(guī)模敏捷燃乍?”
我想答案是:質(zhì)量高英古,效率快澳厢,大家都開心。
參考資料:
SAFe:How the Scaled Agile Framework? Benefits Organizations
SAFe for Lean Enterprises - Scaled Agile Framework
SAFe Lean-Agile Principles - Scaled Agile Framework
A Complete Guide About Scaled Agile Framework (SAFe)? - DZone
文/Thoughtworks 曾雪松
原文鏈接:https://insights.thoughtworks.cn/large-scale-agile-ensures-quality-and-efficiency/