一個真實的敏捷開發案例
Scrum為專案執行提供了可靠的、已被證實的基礎。但是,在每個專案中,Scrum都必須根據具體需求和環境進行調整,這是專案成敗的決定性因素。在這篇文章中,將會介紹如何成功地完成了一個大型的(20人年,超過十萬行程式碼)、分散式(開發人員位於印度和荷蘭)Scrum專案,而這個 專案曾經在傳統開發方式下被廢棄過 。為了幫助讀者順利運作大規模專案,在這裡我也會歷數我們的經驗教訓,包括:專案啟動、找到合適的產品負責人、估算的重要性、有效溝通、測試、文件。
背景
荷蘭鐵路可以躋身於世界上使用量最大的鐵路系統之列,每天要運送120萬乘客。該部門打造了一套全新的資訊系統,為乘客提供更準確的列車資訊,減少人為干預。作為該系統的一部分,我們做了這個PUB釋出系統,對所有車站中的資訊顯示和音訊廣播做集中控制。
有人之前試過完成這個PUB系統,但是他們當時用的是傳統的瀑布方法。客戶把詳細的需求文件規範交給了開發商,然後放任自流,等著完整的系統成形交 付。三年之後,這個專案被取消掉了,因為開發商沒能開發出一個可以工作的系統來。然後客戶僱傭了我們公司從頭做起,我們引入了敏捷開發方式,用上了 Scrum,跟客戶緊密協作,開放交流,小步前進。
起步
專案開始的時候,我們在第一個sprint開始前安排了一個啟動階段,耗時三週,準備好了sprint中所需的一切。這個啟動階段由一個專案經理,一個架構師和一個Scrum___ master參與完成。
選擇產品負責人是個很有難度的事情,我們找不到一個人能夠有時間、具備領域知識、而且有權利設定需求優先順序。我們提名了兩個業務分析師來一起承擔產 品負責人的職責。他們能抽出時間來,而且他們從前也參與過構建PUB的工作,所以業務知識很豐富,足以擔當起產品負責人的角色,為多組客戶充當優秀的代 理。有關優先順序的和範圍的高階決策,是由客戶委任的專案經理負責,但是他時間不夠用,對於需求的理解也有所欠缺。一般情況下大家的配合還可以,但偶爾專案 經理也會對(他所缺席的)計劃會議上制定的優先順序進行調整,於是這個會議就得重新來過。在理想狀態中,對優先順序有最終決策權的人應當每次都參加 sprint計劃會議。
因為先前有人試著構建過PUB系統,所以有些部分的詳細需求文件已經是現成的了。它們遵守了MIL標準[1],不過其形式不適于敏捷計劃和估算 [2],因為在敏捷開發中,需求應當被組織成小塊的段落,每一塊都可以在一個sprint中進行實現、測試和演示,但是現有的文件與此要求不符。產品負責 人也沒有多少編寫使用者故事的經驗,為了解決這個問題,Scrum___ master幫他們弄出了最原始的產品backlog,裡面放著一些細粒度的、經過估算的使用者故事,供前幾個迭代使用。
我們所構建的軟體只是某個大型軟體系統的一部分,它還包括很多相關的軟體系統,那些系統負責顯示資訊,還要在車站內安裝相關顯示裝置。我們得保證每 件事情都可以按時完成,才能把複雜的系統理順。所以需要有一個整體的計劃方案。經歷了幾次迭代,我們對系統的各個功能都按照自己的最大能力做出估算,這個 問題也解決掉了,而且也有了一個比較靠譜的生產率。於是就可以用釋出版本燃盡圖來記錄和溝通進度了。這裡我們學到的東西就是,即使是資訊量很少的情況下, 有估算也比沒估算好。
擴充套件到分散式團隊
專案啟動以後,一開始只有7個人,兩星期一迭代。專案從一開始就計劃著要用到印度的一些人力,所以從第一個sprint開始就有兩個印度開發人員進入了團隊。他們來到客戶現場參與開發,用了六週時間熟悉領域知識、使用者代表和團隊其他成員。
建立團隊伊始,就要決定如何協作。我們跟所有團隊成員一起——也包括印度同事——組織了一個“規範和章程 ”活動。我們定下來一些實踐方式,如怎樣做結對、用哪些工具、質量目標、每天的核心工作時間等等。然後在Wiki上記錄下來。整個團隊有了共識,事情就好 辦多了。一旦這些共識需要修改,比如在回顧會議上提出改進,這些實踐就要在wiki上更新,這樣有新人加入的時候,他們看到的總是最新內容。
在前幾個迭代裡面,團隊成功地構建、測試、驗證了組成系統核心的使用者故事。這讓客戶很滿意,尤其是跟過去相比,我們的進度更快,而且客戶對專案的方向也有掌控權。
幾個迭代以後,我們就擴充套件了專案:印度的開發人員返回本國,然後我們在印度和荷蘭都增加了資源,這樣變成了兩個Scrum團隊,每個團隊5個開發人 員,共享同一個測試人員。過後又變成了三個團隊,一共三個測試人員。每個團隊都既有印度員工,又有荷蘭員工。這種方式讓專案保持了很高的生產率和工作質量。
那我們是怎樣異地協同工作的呢?首先,我們頻繁使用Skype。我們都有網路攝像頭、耳機、麥克風,還有個大螢幕。所以我們既能一對一開會,也能全 體參會。這些都用的是現成的東西和免費軟體。沒多花多少錢,只是用UPS保證斷電的時候也能繼續開Skype會議,這樣提高了印度那邊的網路聯絡能力。其 次,只有在同一個地方的人才做結對。也就是說印度的人跟印度的人結對,荷蘭的人跟荷蘭的人結對。經驗告訴我們,不管現在有了哪些工具,結對程式設計所需的互動 協作還是需要兩個人坐在一起的。
最後,我們用ScrumWorks記錄誰在做什麼事情,記錄Sprint的進度。因為我們是分散式團隊,所以這個比白板要好得多。在跟產品負責人討論產品backlog的時候,ScrumWorks也起了很大作用。
在實施這種分散式模型的時候,我們也戰勝了很多困難。例如,產品負責人不習慣說英語。按照Scrum的說法,計劃會議分成兩部分,在第一部分中,產 品負責人給團隊講述使用者故事,並且設定優先順序。因為這種語言障礙的存在,這一部分的會就只讓荷蘭團隊參加了。第二部分通常是大家討論具體任務,做估算。這 部分是跟印度團隊一起用Skype來完成的,說的是英語,產品負責人不參加。我們還多花一些時間來溝通第一部分會議的內容。Sprint演示也只在荷蘭進 行。完成以後,荷蘭團隊再寫封內部簡報,告知印度團隊——也包括公司其他人——演示的結果。事實證明,這個內部簡報深受歡迎。
拆出一個只關注架構的團隊
我們的專案只是整個應用鏈條中的一部分,必須要跟客戶現有的IT基礎架構無縫掛接。雖然我們的產品負責人對核心功能需求非常熟悉,但是在安全、日 志、可用性、效能等方面就所知甚少了。要從客戶的組織中瞭解這些需求難度很大,因為這得跟不同部門中的許多人溝通討論。這種調查工作給Scrum的迭代節 奏拖了後腿。為了解決這個問題,我們建立了一個獨立團隊,他們只關注架構方面的內容。他們的工作就是弄清楚非功能性需求,好讓我們把它們轉換成 backlog中的使用者故事。我們用“Scrum of Scrum”會議來跟特徵團隊溝通。我們都喜歡這種方式,因為特徵團隊可以全速前進。而且有些員工也喜歡在“架構團隊”中工作。
文件
客戶要求大量的文件,而且還要符合MIL文件規範。還要用荷蘭語寫。很明顯,這項工作只能由荷蘭人來幹。而且開發跟測試都不熟悉MIL規範,寫使用者 手冊這樣的文件也不是他們所擅長的。所以我們決定僱一個曾經寫過MIL文件的技術文案。開發跟測試可以繼續關注於各自職責。這個做法也很成功,不過我們發 現這也要求技術文案和其他團隊成員之間也要有大量的溝通交流,這是需要引起注意的,因為開發人員只想“做他們該做的事情”。
需求管理
我們的產品負責人是一些業務分析師,他們習慣於用荷蘭語寫出大量的需求文件。而在我們的過程中,只要backlog中有使用者故事,產品負責人也能在 計劃會議上做解釋,這就足夠了。但是客戶又要求有很多文件。所以我們打算和產品負責人一起把需求翻譯成使用者故事。結果就是需求被放在了兩個地方:需求文件 和 backlog。當需求發生變化的時候就會導致問題。我們做了大量的輔導工作,確保產品負責人不僅僅是關注需求文件,也要負責backlog。
有了一行文字表達的使用者故事,再加上產品負責人的解釋,我們的Scrum團隊就可以構建和測試軟體了。不過需求文件對外部的測試團隊做測試還是很有價值的,雖然在好些迭代裡面,我們很難把實現的使用者故事跟需求文件中的某些部分“對映”起來。
回顧從前,我們其實一直都沒有一個理想的需求管理過程。我們只是盡了最大努力,來應對這相互衝突的需求:我們需要使用者故事,客戶需要詳細的需求文件。
測試
我們在專案中做了自動化測試,保證在每個Sprint結尾的時候都可以交付經過測試的軟體,不帶有迴歸的bug。即使隨著系統擴充套件,我們還是做到了在8人的Scrum團隊中只安排一個測試人員,而且保證了高質量:外部測試團隊最多也就是能在每千行程式碼中發現一個缺陷。
我們的自動化測試包括兩部分:單元測試和驗收測試。在前者中,我們用的是JUnit,用Clover度量測試覆蓋率,我們的目標是伺服器端程式碼的測 試覆蓋率達到80%。驗收測試用FitNesse作自動化。每個完成的使用者故事,都會在FitNesse上有一套驗收測試。有了龐大的測試套件,就能在 Sprint中找到並修復迴歸的bug。這種做法還有另外一個好處,就是測試人員從一開始就可以積極參與,在使用者故事實現之前編寫測試用例。
有一個地方讓我們苦惱了很久。這個系統有一部分是一個使用者介面很複雜的富客戶端。對這東西做自動化測試要比對服務端做測試難得多。所以在UI方面的 功能我們大部分還是依靠手工操作。隨著系統的增長,回顧測試所花的時間就越來越長,更糟的是,外部團隊只在這部分系統中會發現迴歸bug。如果有了自動化 測試就能防止這一點。我們由此學到了一點,即便是自動化測試很困難,為它付出些努力,遲早會獲得回報,尤其是在專案晚期。
產出成果
客戶對我們的工作很滿意。說點馬後炮的話,跟大多數專案一樣,功能、時間、預算都會隨著專案進度發生變化,所以“按時按預算”完成只是個很模糊的完 成標準而已。更為重要的是,我們在專案程序中常常跟客戶討論怎樣把專案做好,他們都很滿意。不幸的是,因為其他系統中的問題,產品在全國範圍內部署的時候 出了麻煩。
客戶找了外部的稽核公司來稽核這個軟體。他們的結論是:
1. 系統的可維護性非常好。
2. 原始碼質量非常高。
在稽核公司的報告中,他們說他們從來沒有給過一個專案這麼多正面評價。
總結
下面是我們從這個專案中學到的最重要的幾點:
1. 很難找到一個既有豐富的需求知識、又有權利設定優先順序的產品負責人。所以人們往往都要用幾個人一起扮演產品負責人的角色,尤其是在大型專案裡面。
2. 如果一定要按期完成工作,那就得保證產品backlog的完整,也要做好估算。對需求而言,即便資訊量很小,有估算也比沒估算的好。把估算跟團隊生產率合併以後,釋出計劃就有了必要的資訊。
3. Scrum對多個分散式團隊很適用。我們每個Scrum團隊都既有荷蘭人又有印度人,這很好地發揮了團隊精神,讓我們注重有效溝通。在溝通中,利用現成的硬體和免費軟體能節省成本。
4. 在啟動分散式專案的時候,先把大家都聚到同一個地方,讓大家對團隊實踐達成一致,這點效果很好。
5. 對於不適合放到Scrum Sprint中的工作(比如尋找關鍵人員,跟其他客戶部門交流),可以讓一個單獨的團隊去做,這樣效率更高。特性團隊可以集中精力開發軟體。有一個專職的技術文案也很好,即便這會增加溝通成本。
6. 雖然軟體開發過程不需要大量的需求文件,但客戶可能需要。不過在Scrum專案中,需求文件代替不了使用者故事。如果既有需求文件,又有使用者故事,那就得在做計劃的時候,就要考慮到在兩個地方協調需求的額外開銷。
7. 在增量式交付軟體的過程中,自動化測試發揮著關鍵性作用,它可以排除迴歸bug的干擾。在專案結束之前,投資回報會高過成本的。