內修敏捷開發心法 + 外煉持續整合招式

說好的軟件質量

提升軟件質量是我們一直追求的理想,但軟件開發唯一不變的真理就是變,爲了應付變化多端的軟件開發過程,敏捷開發提倡了一種擁抱變化的軟件開發理念,少說也替軟件開發人員帶來了不少小確幸。

這些軟件開發模型與方法論,最終的目的在於軟件開發管理與質量的提升,與其說質量提升倒不如說是維持一定的水平。雖然敏捷開發有很多不同的方法論 (例如 ScrumXP 等等),但我們注意到這些方法論都一定會提到「持續整合 (Continuous Integration)」這個概念。持續整合到底是何方神聖?讓它在軟件工程中被如此受重視。換個方式來說,我常把敏捷開發比喻爲武功心法,心法是虛的,代表方法論核心的理念,其招式纔是起作用的媒介,然而持續整合便是敏捷開發實現的武功招式之一。

掌握軟件開發節奏

先不管敏什麼捷開什麼發了,先說說爲什麼要推薦各位「持續整合」這個招式。在軟件開發一定相當重視項目管理,因爲軟件在建構的過程中含有太多不確定的因素,項目永遠 Delay。經常發生在產品開發後期,系統漸漸開始浮現各種 Bug 與不穩定的徵兆,越後期的版本提交期限 Delay 機會越高。持續整合就是爲了避免這樣的情形發生,我認爲持續整合最大的好處在於能夠「掌握軟件開發節奏」!

蛤?什麼是軟件開發節奏?這其實表示着我們對軟件開發項目的掌握性,能夠確保軟件在承諾的時間下,交付出合乎規格與質量要求的產品。在持續整合的過程中,我們會隨時將軟件當下的健康狀態透明化,這些狀態一旦透明化,問題就容易被顯現,問題進而容易被掌握與排除。而不是交付到客戶手上,才發現某個功能有問題。通常的軟件開發項目都有以下幾個願望:

· 程序設計師想踏實地寫程序

· 項目經理想確實地掌握時程

· 組織想降低成本與開發風險

· 客戶想拿到質量優良的產品

我們也希望藉由掌握軟件開發節奏讓這些願望實現!

快避免由病轉疾

若是我們長期參與低劣的軟件開發過程,久而久之就容易失去信念,失去對軟件質量的堅持,這對於組織與團隊的傷害相當大,但也因爲不易根除,往往日久爲患。工程師爲了項目時程而加班,PM 爲了時程犧牲品質。程序設計師漸漸爲了趕緊搞定眼前的難題,開始不踏實地建構軟件,開始用一些奇怪的方法 (Dirty Hard Code) 解決系統自動產生的 Bug...。我想您應該明白這些奇怪的方法指的是什麼?時間一久,我們對軟件的感情就淡了,反正有了摩菲定理的加持,項目一定延遲,Bug 永遠改不完。我們面對軟件開發的複雜性,不知不覺已經由病轉疾,病可以醫的好,疾就只能控制病情了。

那持續整合到底是什麼?

假設我們能隨時掌握軟件的狀態,讓開發中軟件一切的狀態變得透明,那不是很好嗎?回到「持續整合」這個議題,簡單從字面上解釋「持續」就是「不間斷、不停地、一直、有事沒事就做一下」大概這樣的意思;那「整合」呢?在軟件開發中的整合不就是「把大家寫的 Code 在一起跑看看有沒有錯!」。以此類推「持續整合」四個字的意思就是「有事沒事就把大家寫的 Code 在一起跑看看有沒有錯!」,聽起來很簡單吧!?

我們先來講講持續整合的用意好了,我們常接觸的敏捷開發 (Agile),爲了快速適應變化,常常在很短的週期 (Scrum 大約兩週就會發佈一個新版本,這件事在 XP (極限編程中稱爲 Small Release。然而每一個版本發佈重視的不是新增的多少功能?而是產生一個逐漸接近市場的產品。注意喔,每次發佈的軟件都必須是可以被正確執行的!在很多敏捷開發方法論都提到,可正確執行的程序碼勝過一切,當然也勝過那些該死的文件。

問題來了,要如何在短時間驗證軟件是可以正常運作的呢?如果一開始功能少還可以花點時間手動測,到後期功能多就沒辦法了,更不用說除了測試新版本的功能,還要確保既有的功能能夠運作正常。這時候「持續整合」就是發揮效用的時候了。回到剛剛提到的:「有事沒事就把大家寫的 Code 在一起跑看看有沒有錯!」這樣的事情對我們而言,其實就是自動地從版本控制系統拉 Code 進行建置與測試,一旦我們不停的在開發的過程中持續地進行這件事,當軟件發生不穩定時就可以立即察覺,將能夠大幅降低整合測試的風險與時間,因爲我們隨時隨地都在進行整合測試!

關於測試與自動化

上述提及的測試並非手動測試或半自動測試,而是全自動測試。在必須反覆且密集測試的過程中,我相信你不會想要手動測試的 (花錢找工讀生測也不是辦法),而且只要是人做的都有機會錯!自動化測試會是比較好的方法。

在實際上,對於「撰寫測試」這件事,大概是整個持續整合過程中最難推動的,常因爲我們的教育一開始就沒有讓新手程序設計師明白測試程序的重要性,日常的工作也都是在追求功能的實現,而不是功能正確無誤地實現,往往只重視在程序本身的執行結果 (用眼睛看)。在敏捷開發中,也曾提到測試驅動開發 (TDD, Test-driven development) 這樣的概念,但如果您開發的系統沒有經驗老道的軟件架構師,那麼這個模式在實務推行上將更爲困難,因爲常發現根本沒辦法在既有的軟件架構設計自動測試,要改就得大改,實行測試的信心與意念就被消滅了。

在實作測試的過程中,其實有些重新審覈系統的味道,象是我們都可以發現更多軟件設計上的缺失,發現更多可以改進的設計,象是利用解耦合、物件抽象化、資料連結層 (Data Access Layer)Mock ObjectDummy Data 等等技巧對架構進行軟件重構。實行測試還有另一種很棒的方法,就是實行「結對編程 (Pair Programming)」,但這跟測試有什麼關係呢?我們先想想,在結對編程中常常一位寫程序另一位寫測試,這樣的過程迫使我們能夠設計出可被其他程序測試的程序碼,間接達到自動化測試。許多組織高層的觀念必須調整,有的老闆很難理解爲什麼要兩個人做同一件事,但公司卻要付兩個人的薪水!

實行自動化測試困難重重,但這些都不是我們逃避的原因,其實一開始不用急着提高測試覆蓋率,先從基本的功能測試開始。大致上有兩個方向可以慢慢實現:

1. 先進行基本功能的正確性測試,至少保證功能可以被執行(雖然不一定對)。

2. 當系統出現 Bug 時,解 Bug 前撰寫複製錯誤的測試程序,接着才修正 Bug 確保未來同樣的 Bug 不會一再發生。

這兩點對於已經開發中的系統特別有效,可以慢慢搭建起自動化測試的工作,有了開始就容易多了。我曾經看過實際的例子,在一個開發已久的軟件後期才加入自動化測試,雖然覆蓋率不到 30%,但是管理者做了一個很有約束力的決策,就是整合版本控制系統,未來 Commit 的程序碼不能降低整個系統的覆蓋率。所以每次 Commit 後就會進行自動測試,約束未來加入的程序碼必須強制撰寫自動化測試,保證產品的質量不會越來越糟。

測試的模式與種類繁多,試着找出適合自己產品的自動化測試手段即可,並沒有一定的標準答案。最後,儘管我們可以達到的測試覆蓋率有限,或者當下複雜的軟件架構導致難以撰寫測試,但這些都不是藉口,必須先開始纔會有進步的空間。

系統反饋

前面提到,由於持續整合系統無時無刻都在進行系統整合與測試,當持續整合發現軟件不穩定時(指的是建置或測試失敗),就會發出警示給予開發者。這個行爲我們稱爲「Feedback 系統反饋」,系統反饋是持續整合系統中相當重要的一件事。當我們收到系統給予我們這樣的反饋時,應當立即着手處理,而不是拖到接近產品釋出期限,纔開始面對持續整合早就給予我們的警示,造成產品時程與質量的憂慮。

最容易實現系統反饋的方法可以透過「每日建置」來完成,每日建置通常在晚上執行 (或稱爲 Nightly Build),由於通常身心正常的程序設計師會在下班前提交比較穩定的程序碼,在夜深人靜的時候進行整合測試是一個好方法。由於系統每天晚上會更新最新的程序碼進行建置,當遇到問題時就會發出「系統反饋」警示,通常是發出 Email 告知幾位相關衰人,好讓事主在隔天一早上班就可以着手處理問題,儘可能讓我們所建構的軟件在軟件開發過程中,能夠隨時保持穩定的狀態。若是在合理的測試覆蓋率下,甚至可以隨時發佈開發中的系統,「快速適應變化」這不就纔是敏捷開發的精神嗎?

持續整合的精神:自動化 測試 系統反饋

由於每個軟件項目都不盡相同,軟件建構流程並沒有絕對的標準答案,只有做適合團隊的對應作法。實務上建置持續整合系統,確實要花上不少功夫撰寫 Script 建置腳本,特別在測試環境的自動化建置與執行測試等等工作。雖然方法不同,但是所有的概念還是環繞在「自動化+測試+系統反饋」這三個精神上。我認爲我們都需要一種義無返顧的勇氣,好讓我們持續在持續整合工作上投入心力,讓軟件變得更好!我相信我們都能打造出讓自己也能驕傲的軟件!

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章