14
ii 記得剛進入軟體開發這個行業時,前輩常常來到我的座位前面關心專案的進度, Hi S 君,程式寫完了沒呀!不就是“打打字”,應該沒問題吧?」懞懂的我當時 覺得要趕快把程式寫一寫,讓專案可以趕快結束是最重要的事情。後來隨著經驗的 累積,也離開了當時的第一份工作的公司,才瞭解快速把程式寫完已經不是首要的 目標,反而該重視的是測試、程式碼檢閱(Code review)以及如何進行程式碼重 構(refactor)等這些真正影響品質的項目,工程師之間常以“刻程式碼”來描述 程式撰寫的工作。就像木作刻雕一樣,很少一氣呵成便輕鬆完成作品的,需要的是 不斷地敲敲打打或是從旁側擊,經過許多的修正,最後把雕像完成。開發軟體也亦 如是,我們不太可能寫出 bug free 的程式碼,唯有持續不斷的檢視修正才能造就好 品質的程式。 最近隨著 APP 時代的來臨,軟體市場大開,讓很多企業開始轉向開發相關軟體, 甚至許多受歡迎的軟體皆是由素人開發者所提供,據統計 2012 年全球 APP 軟體開 發者 / 團隊的數量便達到 300 萬名之多,這還不包含仍然蓬勃發展的 web 網頁開發 者。由於軟體數量及需求如雨後春筍般不停地被產出,軟體開發方法也出現了許多 演進,其中最受歡迎的便是敏捷開發方法 (Agile development method),持續整合 工具也是被廣泛採用的解決方案之一。 持續整合 (Continuous integration) 在目前熱門的敏捷開發方法或測試導向開發方法 論中扮演相當重要的角色,是讓系統開發在快速變動的需求下,仍能維持高軟體品 質的重要條件。而 Jenkins 便是實現持續整合的首選工具,透過此自動化的軟體建 置工具讓企業能快速驗證軟體版本演進的缺失,更能方便地整合現有各種原始碼管 理方案以及各種軟體建置方法。本書將提供讀者快速瞭解 Jenkins,還有如何整合 其他開發工具,以及透過範例解說如何撰寫 Plugin 程式來擴充 Jenkins另外,書 中將以作者修改貪食蛇遊戲專案為範例,以此遊戲專案開發做為持續整合的導入實 例,最後附送作者為此貪食蛇遊戲所加上的虛擬方向鍵功能程式碼。

APPepaper.gotop.com.tw/PDFSample/ACL037600.pdf · 心滿意足地等到該星期的任務會議到來,但是最後在會議中與大家一整合後才發現 原先任務雖已達成,但需求總是變化得比你的程式碼還快,又或許是設計方向有錯

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

ii

記得剛進入軟體開發這個行業時,前輩常常來到我的座位前面關心專案的進度,

「Hi S君,程式寫完了沒呀!不就是“打打字”,應該沒問題吧?」懞懂的我當時

覺得要趕快把程式寫一寫,讓專案可以趕快結束是最重要的事情。後來隨著經驗的

累積,也離開了當時的第一份工作的公司,才瞭解快速把程式寫完已經不是首要的

目標,反而該重視的是測試、程式碼檢閱(Code review)以及如何進行程式碼重

構(refactor)等這些真正影響品質的項目,工程師之間常以“刻程式碼”來描述

程式撰寫的工作。就像木作刻雕一樣,很少一氣呵成便輕鬆完成作品的,需要的是

不斷地敲敲打打或是從旁側擊,經過許多的修正,最後把雕像完成。開發軟體也亦

如是,我們不太可能寫出 bug free的程式碼,唯有持續不斷的檢視修正才能造就好

品質的程式。

最近隨著 APP時代的來臨,軟體市場大開,讓很多企業開始轉向開發相關軟體,

甚至許多受歡迎的軟體皆是由素人開發者所提供,據統計 2012年全球 APP軟體開

發者 /團隊的數量便達到 300萬名之多,這還不包含仍然蓬勃發展的 web網頁開發

者。由於軟體數量及需求如雨後春筍般不停地被產出,軟體開發方法也出現了許多

演進,其中最受歡迎的便是敏捷開發方法 (Agile development method),持續整合

工具也是被廣泛採用的解決方案之一。

持續整合 (Continuous integration)在目前熱門的敏捷開發方法或測試導向開發方法

論中扮演相當重要的角色,是讓系統開發在快速變動的需求下,仍能維持高軟體品

質的重要條件。而 Jenkins便是實現持續整合的首選工具,透過此自動化的軟體建

置工具讓企業能快速驗證軟體版本演進的缺失,更能方便地整合現有各種原始碼管

理方案以及各種軟體建置方法。本書將提供讀者快速瞭解 Jenkins,還有如何整合

其他開發工具,以及透過範例解說如何撰寫 Plugin程式來擴充 Jenkins。 另外,書

中將以作者修改貪食蛇遊戲專案為範例,以此遊戲專案開發做為持續整合的導入實

例,最後附送作者為此貪食蛇遊戲所加上的虛擬方向鍵功能程式碼。

iii

就如同棒球場上的「一球入魂」一詞,訴求的並不是一球就把對方擊倒,而是認真

的,盡全力地投出每一球,然後取得比賽勝利的意思。「持續整合」的概念也是不

斷地維護軟體品質,把握每一次程式變動,使程式碼得以優雅的演進,讓我們一起

追求程式碼的「一鍵入魂」吧!

本書程式碼的下載網址:http://books.gotop.com.tw/download/ACL037600

邱炫儒

第一章

持續整合

持續整合(Continuous integration)的概念最初是指在專案中由一個主要的電腦或

伺服器來整合所有工程師的工作內容,並且要求每天都需要進行此一整合作業,以

減少長時間累積的程式變動所帶來的影響。簡單來說,就是透過自動化工具將各模

組的程式碼從版本控管伺服器上下載下來,若程式碼有所變動,便進行程式碼編譯

並測試,如果出現問題可以馬上通知工程師進行修正。

但持續整合的效益卻不止於此,除了軟體編譯和自動化測試之外,也可以透過整合

更多如靜態程式碼分析工具來監視軟體專案的健康狀態,甚至作為團隊間的溝通管

道,成員們可以依 Jenkins上所整合的各種測試分析報告進行 Code Review,以及

檢視專案進度。

此外,「方便快速的反映程式碼變動結果」更是許多軟體開發方法論中不可缺

少的基本要素,例如敏捷開發方法(Agile development)、DevOps、持續部署

(Continuous Deployment)等。在使用 Jenkins工具之前,不妨先閱讀此一章節,

瞭解這個領域相關概念。

1.1 土木工程 VS.軟體工程

聽說有個好方法可以改善軟體品質?聽說只要使用持續整合工具就可以輕鬆完成軟

體整合自動化?其實「持續整合」講的是一套方法,或者是專案管理方式,有了良

好的「專案開發習慣」後,我們才能透過自動化工具將這些好習慣串接起來。在學

2

CI(Continuous integration)關鍵技術—使用 Jenkins

習 Jenkins工具之前,先瞭解持續整合的概念是個好的開始,接下來才是思考如何

使用 Jenkins工具為軟體開發帶來效益。首先,我們可以這樣問,誰會需要這種工

具呢?

有經驗的開發者常遇到這種情況:今天程式碼撰寫的工作相當順利,神馳個一小

時,就幾乎把這星期任務完成大半了,在自己電腦上的功能測試也都正確了,因此

心滿意足地等到該星期的任務會議到來,但是最後在會議中與大家一整合後才發現

原先任務雖已達成,但需求總是變化得比你的程式碼還快,又或許是設計方向有錯

誤,但之前無法及時發現,因此下星期需要重新來過。就像下圖中的房子,蓋好了

但已經不符合需求,想要修改卻無足夠資源重建,只好在原來的架構下繼續改建,

最後變成四不像。

圖 1.1 無法及時變更設計的加蓋工程

雖然軟體開發並不像蓋房子,但修改設

計架構仍是個大工程,開發後期的修改

幅度越大,表示與當初期望落差越大,

很多細節一定沒考量到,大變動帶來的

邊際問題一定也更多。這種與需求不符

是傳統軟體開發最害怕遇到的情況,

傳統開發週期長,測試驗證又都放在後

期,因此常會來不及回頭修改設計,若

時間不允許,則只好硬著頭皮植入許多

「workaround」,最後就像蓋出一棟如

右圖般充滿問題的組合屋。

如同一張成功的音樂唱片製作過程,創

作者會確認歌曲方向及風格後開始進行

創作,過程一定是哼哼唱唱並不斷修改,還需要有製作人負責規劃並與其他樂器進

行分工,可能每天都得分別跟團員們進行溝通並「集成」大家的成果進行檢視,過

程中還需錄製許多「DEMO帶」以作為未來修改的參考。最後,一張完美的專輯

才得以誕生,這種頻繁變更設計的程序,其實在軟體開發過程中更是需要採用,因

為沒有人能一開始便規劃出百分百符合需求的系統設計。

3

第一章 持續整合

但寫程式並不像砌磚頭或做音樂般,隨時都可以退後幾步,看看整體外觀對不對或

是錄個 DEMO來聽聽看好不好聽,不管往後退幾碼,程式看起來長的都一樣,無

法看出哪裡有問題。因此寫到一半要停下來檢視狀況,就只能靠執行測試個案或是

進行科學化的程式碼檢查。而如何有效地進行檢視和修改,正是所謂的「敏捷開發

方法」很重要的一環。

在軟體開發上,敏捷方法很早便被廣泛應用於遊戲開發,因為一套有趣的遊戲也是

無法紙上談兵完成的。就算備有完整的設計文件,最後開發出來的遊戲性不好玩就

是不好玩,連測試程式也無法提供有趣性的驗證,因此遊戲常切分細部遊戲性雛形

開發,以雛形快速驗證遊戲性(game play),每次驗證都可以很快回頭修正並進行

下一階段驗證,這種不斷快速迭代式(Iteration)的方法便是敏捷開發。

輸出

流程

輸入

review

retrospective

輸出

流程

輸入

review

retrospective

輸出

流程

輸入

review

retrospective

完成

圖 1.2 迭代式的開發流程

由上圖的示意圖可以看出來,在迭代式的開發循環中很重要的一點是檢視與回饋,

敏捷式方法提出許多確保軟體品質的解決方案來收斂這些回饋所造成的不穩定性,

其中較知名的有測試導向開發(Test-driven development)、兩人共同撰寫程式碼

(pair programming)、例行軟體部署(Daily deployment)、持續整合(Continuous

integration)等。因為開發方式被切成許多循環,上述的迭代式方法也會多產生一

些直瀑式開發方法所沒有的夾縫時間,也就是不鼓勵一鼓作氣將所有需求規格一次

開發完畢,而是期待頻繁地停下來檢視成果。這樣的夾縫時間在敏捷開發方法中被

視為非常重要,換句話說,就是強調往後退一步來檢視程式碼遠比一直趕進度還重

要的概念,如此一來,軟體開發便能輕鬆應對經常性的改變。在本書稍後的章節會

介紹如何利用 Jenkins 工具來進行持續整合,並且自動整合單元測試,讓程式碼版

本順利的演進,非僅是制定繁雜檢定程序來徒增工程師的勞累而已。

4

CI(Continuous integration)關鍵技術—使用 Jenkins

換個角度來說,Jenkins或者是說持續整合工具與軟體開發的關係就像是「軸」與

「輪」的關係,嵌合推進,越緊密則推進越順利,每一回合轉動需要包含的編譯、

測試、部署以及發佈等程序,藉由 Jenkins達成自動化整合。如果把迭代式的開發

循環加入時間以及進度的維度,則呈如下圖的推進模式。由於傳統直瀑式開發的階

段時間太久,常無法敏捷地反映問題,導致預期的專案目標總是滑掉,唯有採用敏

捷式開發才能緊密的輪動。敏捷開發的理論完美無瑕,但若以瀑布式角度來看,實

施上困難重重,縮短的關鍵正是透過自動化測試和自動化建置與部署來增加漸進式

的頻率,讓專案開發敏捷地反應需求和變動。

時間

專案目標

時間

專案目標

時間

專案目標

理想上的直瀑式開發方法 現實上常無法敏捷地反映專案目標

敏捷式開發方法

圖 1.3 讓專案敏捷地反應變動

持續整合的導入不只是安裝 Jenkins並把程式碼都放上去 build就算完成,敏捷開

發所論述的核心價值,其實是開發習慣或是專案管理準則,而非一套按部就班地實

施細節,唯有瞭解方法中倡導的精神和想要解決的問題後,才能有效導入以及適切

地整合所需的工具。在開始使用 Jenkins前,很重要的一點是要思考團隊習慣如何

進行重整,是否已經準備好使用測試導向開發?是否已經安排好如何進行程式碼檢

視會議?確認使用目的及情境後,Jenkins工具絕對能讓軟體開發事半功倍,否則

5

第一章 持續整合

大家因為 Jenkins上線而鬆懈心態隨意提交程式,認為「反正程式放上去,有問題

很快會被找出來」,這反而對品質沒有正面的助益,因為測試找出 Bug、修正程式

並重新測試,這些都是不必要的資源浪費,就如同 Google Testing Blog網站上的名

言一樣「Debugging sucks, Testing rocks」!。

1.2 Who is the guy broke the build?

天天上演的偵探劇

開發過程中,常常會遇到一些因為溝通不良所造成的軟體編譯失敗,工程師便開始

查程式碼無法編譯的原因,是自己程式碼的錯誤嗎?還是別人提供的介面規格不正

確呢?如果是平時沒有隨時整合習慣,等開發後期整合時才發現的話,則需要修正

更多的程式碼來解決。

身為軟體工程師,在工作上一定經常出現這樣的對話:

A: B君,我的部份告一段落了,想要拿你那部份來整合看看,可以丟你編譯好的 library給我嗎?

B: 好啊?之前開會提到的資料庫查詢介面也都做好包在裡面囉!

A: 疑?我改用你這版 library之後就編譯失敗了耶?查詢訂單資訊的參數怎麼是 int,後來不是要改字串嗎?

B:是喔,怎不早講。我 DAO物件和 DB欄位都開得差不多了耶。

類似的情節想必你我都不陌生,大部份軟體專案都是需要團隊開發,人一多就會有

溝通不良,細節無法彰顯的狀況發生。導入 Jenkins後,最直接感受到的優點便是

這個問題被輕易地解決了,因為 Jenkins可以整合各種程式碼版本控管工具,哪一

個工程師在哪一個時間點上傳了程式碼,以及這個版本是否導致建置失敗,這些資

訊都被集中於 Jenkins網頁上統一呈現,如果團隊開發進展到 Daily deployment的

話,這些問題在當天就可以發現,即早解決。

在此案例中,精確的整合看起來是必然的解法,但有些時候解決這種問題的做法卻

是交代某個工程師每天固定時間去整合程式,對這位工程師卻是噩夢的開始,因為

這樣子的工作並不簡單,下個章節便是個有趣的例子。

6

CI(Continuous integration)關鍵技術—使用 Jenkins

1.3 《奔馳的代碼》Project Code Rush

提到軟體專案的團隊合作,我們不妨將時光回溯至 1998年,那是網際網路崛起的

時代,當時紅極一時的 Netscape網景公司因為面臨微軟 IE瀏覽器的市場挑戰,想

要把 Netscape瀏覽器改為開放原始碼專案的方式經營,也就是後來著名的 Mozilla

專案。把一個軟體專案在有限時間內整個重構成適合開放原始碼需求的版本,無論

是經營策略或是技術領域本身,在當時都被各方高度關注,甚至這段故事也被拍成

記錄片「Project Code Rush」註 1,在這邊推薦大家到 YouTube上搜尋此一影片,一

觀網際網路啟蒙時代的奮鬥史,從現在的時空,回頭再看前人如何揣摩未來世界的

模樣,很是有趣。除了世界上不再有閃爍的 CRT螢幕之外,一直都沒變的是科技

界或者說是新創領域上的一群奮鬥者,想盡辦法抓住一點點可能竄出的趨勢而努力

的模樣,從以前到現在都沒變。

在這部記錄片中,Netscape公司正嘗試在發佈日之前把程式碼重整並想把已知問題

都加以修正,當時的做法是將所有工程師聚集在一起四目對望,並條列出整個黑板

的改善計劃。趕進度的過程中,所有人都蔓延著不安與焦慮,不曉得自身產出的程

式碼是否已經達到計劃中的目標,也不曉得問題是否解決。在固定的時程下,會有

一位工程師負責整合大家的程式碼並編譯最新的瀏覽器版本,當大家正慶幸這次的

程式整合竟然異常的順利且成功編譯完成時,下一秒畫面出現的竟是瀏覽器啟動失

敗的錯誤訊息,從天堂掉落地獄的工程師們便嘆息著開始進行除錯工作。負責整合

的工程師壓力相當大,看管約兩百五十萬行的程式碼,這些程式碼由兩百多個工程

師所貢獻,如果無法確保這些大量的修改不會讓 Mozilla當掉的話,數百人的工作

將會因此停滯。

註 1 《奔馳的代碼》(Project Code Rush)是 1998年一群 Netscape工程師在矽谷的生活記錄片,導演David Winton記錄了原本是一個獨立公司製作的 Netscape瀏覽器,後來發佈成為 Mozilla的開放程式碼項目,直到他們最後被 AOL收購這段時間的歷程。記錄片中特別側重於發佈 Mozilla版本前工程師們的匆忙時刻,忠實呈現了科技矽谷的工作面貌,在市場行銷上,也被視為微軟巨人壟

斷瀏覽器市場的重要事件,在科技界來說,也可視為「程式碼重構」的經典故事。

Code Rush網站: http://clickmovement.org/coderush。 http://moztw.org/events/code-rush/

7

第一章 持續整合

圖 1.4 mozilla專案的挑戰之路註 2

當然光靠一個人是無法收集程式碼並執行所有編譯工作的,尤其 Netscape的所有

程式碼當時是由兩百多位工程師所貢獻,如同記錄片中所闡述:

「就算是 20個人的團隊打造一台車,只要稍微退後看,便可以看出誰少裝了一

個輪胎,但 20個工程師每個人都拿著程式碼來找你,手中拿著由許多微小細節

所組成的磁片,通常你無法單獨判斷這些是否正確,你必須要先組合這些程式,

再看看整體能不能動,你甚至無法確定是誰寫了那些錯誤片段。」

因此當時他們開始自行開發一套軟體建置系統,嘗試追蹤每一筆修改的狀況,一遇

到問題,便需要徹夜除錯,以確保時程不會因此而延宕。這個軟體建置系統或許不

能說非常完善,所以記錄片中還曾出現拿著曲棍球棒在公司內找問題的負責人的有

趣景象。

Netscape的故事可說為開放程式碼社群的蓬勃發展史開了第一槍,此外,這種為

了阻止問題的發散,嘗試要快速地確保每一筆修改的經典案例,也可謂是「持續整

合」概念的濫觴。

註 2 Netscape以及 mozilla project標誌為 Mozilla之商標或註冊商標

8

CI(Continuous integration)關鍵技術—使用 Jenkins

1.4 But it works on my machine

大部份工程師都有自己偏好的開發環境,曾經我與一位同事在其座位討論一個程式

問題,他用 vim打開程式碼,快速地修改檔案並用自己開發的腳本工具執行程式

結果與我討論,等我要抒發自己意見的時候,只習慣使用 eclipse IDE的我侷促地

不知如何下手;有時候甚至與相同都是 IDE愛好者的同事,操作他的電腦討論個

案時,仍是不太上手。或許我們可以強迫統一的開發環境,但每種工具其實都有優

點跟缺點,偏偏這些不願統一的都是程式好手,讓他們用自己習慣的節奏來工作其

實會有更好的產出(這也是為什麼一些強調高創造力的公司並不喜歡限制員工們的

開發工具,如 Google、Facebook)。為了讓團隊間的溝通有一個順暢的橋梁,我們

可以在公用工具 /流程上統一標準:用同一套程式碼版本控管伺服器、用 Jenkins

統一進行軟體建置環境,以及規定定期提交及整合程式碼的時間,有了一定的默契

後,工程師自己的開發環境甚至可以放任其自由發揮卻不會影響團隊間的合作,而

導入的 Jenkins便成為溝通的媒介。

例如針對某一個軟體專案,我們可以定義標準產品產出的方法,而非想辦法統一每

個工程師的電腦環境:

z 使用 perforce 程式碼控管

z 使用 Ant編寫編譯腳本

z 測試個案涵蓋率須達到 80%以上

z 每天定期編譯版本並為每個版本進行測試

z 每個星期挑選穩定版本進行部署

z 使用 Jenkins整合以上流程

團隊成員認知 Jenkins上面便是標準公開的軟體建置腳本,讓開發環境和軟體正式

建置環境盡量達到無縫式的銜接,就不用常聽到「可是在我電腦沒這個問題啊!」

的抱怨和爭執。

有些公司甚至提倡並非只有產品經理可以制定流程,人人都能針對產品流程植入想

法,也就是人人都對產品負責的概念。要做到這個目標的關鍵是流程透明化,並非

產品經理口述或僅訂於某一份文件中,而是讓流程透明且自動化的執行,流程可能

產生的問題可以顯而易見地攤開在大家面前被討論。

9

第一章 持續整合

Dev vs. Ops

另一個常見的隔閡則是發生於開發版本與正式版本間的差異,造成有一些問題只有

在正式版本會出現,而在開發版本間根本不曾存在,這類的問題根源可歸類於開

發與業務間的立場不同,這也是所謂的 DevOps方法論註 3的主要論述。我們可以把

DevOps看成是軟體工程(Dev)與商業營運(Ops)之間如何緊密整合的課題,通

常 Dev一方會希望趕快交付程式碼,而 Ops一方,例如 Project Manager則希望保

持軟體的穩定,不願意頻繁的程式碼進版。另一方面,許多企業常於正式發行的版

本中才開始放入屬於商業版本的設定,因此正式商業版本的問題在開發時期很難被

開發者發現,而且開發環境很難搭配各種商業版本的設定進行測試,一旦發生,開

發工程師便需要在不方便的開發環境中除錯。因此 DevOps方法論主張透過頻繁的

發佈活動,讓開發與商業營運可以無縫式的整合,並降低軟體發佈的風險,簡單來

說,達成此一目標的方法可以歸類為下述幾點。

時間

變動

時間

傳統瀑布式開發方法 敏捷式開發方法

變動

圖 1.5 頻繁地掌握專案變化可有效降低風險

z 頻繁的版本部署

通常累積越多程式碼版本所造成的邊際問題(side-effect)會越大,這也是以一

般商業營運或是專案管理者角度最不願遇到的狀況,如上圖所示,每個圓點皆

是程式碼變動的高峰,高峰值越大產生的邊際問題也可能越大,透過頻繁且快

註 3 DevOps是於 2008年的 IT業界慢慢興起的一個名詞,主要是強調如何強化軟體部署以及減少開發與營運作業間的隔閡,目前尚無標準定義,網路上也存在各種的說法。相關資料可參考專門探

討 DevOps相關議題的研討會以及網站:

http://devopsdays.org/ http://dev2ops.org/

10

CI(Continuous integration)關鍵技術—使用 Jenkins

速的版本發佈可以敏捷的修正問題,也可以有效地讓高峰值縮小至能掌握的區

間,反而有效提升軟體穩定的關鍵方法。

z 自動化的版本發佈流程

快速頻繁的進行軟體發佈並非減少原本的品質檢測程序,而是透過自動化的整

合讓流程可以順利接軌,也可以減少人為出錯的可能性。

z 將正式版本的測試盡量往前至開發時期執行

在傳統的瀑布式開發中,開發、測試以及發佈的階段過長,當大量的程式版本

累進至正式版本的測試後,問題的發現及修正也因此被累積至相當後期。若我

們頻繁地進行版本發佈,其實就等於時間上將正式版本的測試提前進行,盡其

可能地檢視所有程式碼差異的可能出現的問題,這可說是「持續整合」真正的

關鍵效益。

z 清晰的版本管理及問題追蹤

一個版本的發佈需要經過一連串的作業,如程式碼管理(SCM)、編譯、測

試、問題回報與追蹤到系統部署等,每一階段都可能有不同人員以及部門參

與。因此要彌合開發與營運之間的溝通鴻溝,除了各種協同工具之外,必須要

有統一的版本編號管理來追溯每個版本的狀況,從測試到問題追蹤都可以快速

追溯至哪一個版本,甚至做到問題回報及發佈更新都可以自動化透過網路完成

(OTA)。

1.5 Eat your own dog food

「Eat your own dog food」,是一句英文的俚語,並不是真的要吃狗食的意思,此

用語一開始常見於 IT業界之間,也有人使用「dogfooding」一詞,意指平常就應

該常使用自己的產品,希望能將員工自己的使用經驗或是使用上遭遇的問題回饋於

產品開發之上。根據維基百科的記載,此俚語最早可能追溯於 1988年,當時微軟

的高階主管保羅•馬瑞茲寫了一封標題為「Eating our own dog food」的郵件給公司

的軟體測試主管,在郵件中提出希望提高內部使用自己產品比重的要求,此用語便

因此傳播開來,甚至現今也有許多非 IT範疇的公司也常喜歡使用這句話來激勵員

工,提升對自家產品的信心。

11

第一章 持續整合

雖然是期望大家要多使用自身產品,讓產品即早於開發階段便可以開始接受檢視,

但其實 dogfooding自家軟體的真正意涵卻不僅於此,成功關鍵是「一個健全完善

的開發建置流程,其流程本身是否具備足夠的條件以提供 dogfooding的需求」。

例如,無論是接近穩定的 beta版本或是 RC版本(Released candidate,發行候選

版本),都必須要讓每個員工使用時有一致可追溯的版本編號,而產品本身能達到

「每日建構版本」,也就是系統能夠每天都建構出最新的程式碼版本,而且員工

可以透過自動更新的方式取得更新,當試用過程遭遇問題時,可以明確地辨識手

上的軟體版本,並且這個版本可以順利的對應至程式碼版本控制系統上。如此一

來便可大大提升 dogfooding的效率,讓公司產品能夠以最快的速度從開發階段進

入真實的使用環境,我們可以這樣說,真正的 dogfooding,其實是「Continuous

Dogfooding」。

本書所介紹的 Jenkins工具更是幫助公司達到「dogfooding」的好幫手,除了每日

建構版本之外,Jenkins甚至可以整合如 Bugzilla等的 issue管理系統,讓使用者所

回報的問題可直接系統化地與版本建構整合在一起。

1.6 軟體品質最佳方案:持續整合

持續整合源自於工程師對自己的邏輯思考所進行的追根究底過程,真正的程式碼撰

寫同時也是邏輯正確性與效率性的討價還價,因為程式碼都是人寫出來的,世界上

並不可能有 bug free的完美程式碼,只有倚靠良好的專案管理方式來減低缺失並提

升程式碼品質。然而不間斷地對每版程式碼的演進進行測試及檢查,的確可以將問

題找出來並快速修正,但每天頻繁地進行此活動需耗費更多資源,試想一下,老闆

每天要求你 build一個版本出來測試,並且繳交單元測試報告及程式碼分析報告,

如果當天 build失敗,你還要去查出昨天是哪個同事提交的程式碼有問題,光做完

這些事情,自己就沒時間寫程式了。為了把這些煩人且重複的工作自動化,讓軟體

持續演進並有效率做好品質控管,於是有了持續整合工具的誕生!

使用 Eclipse 也是一個類似持續整合的例子,廣義上來說,每打一個字、一行指令

就是對軟體作演化,Eclipse 的語法檢查是在打字的過程中執行,馬上看到結果進

而做出反應、反覆修改達到持續整合,目標是將軟體演進的衝擊幅度降到最低。

12

CI(Continuous integration)關鍵技術—使用 Jenkins

在下圖的縱軸是一般的軟體建置流程,時間橫軸是根據流程所衍生的每天例行工

作。Jenkins/Hudson工具可以將縱軸流程自動化串接整合起來,因此軟體工程師便

可以專注於其程式碼開發上,大家也可以有效率地檢視版本演進中的缺失並改善

它。持續性的整合概念便是盡量讓程式碼的每次演進都可以快速地進行縱軸的流

程,降低問題發散的可能性,並且能很敏捷地檢視軟體設計以及確認需求。換句話

說,持續整合其實是常常進步、天天進步,設定 Jenkins工具只是開始,不是結束。

程式碼管理

程式碼編譯工具

靜態程式碼分析工具

單元測試

Perforce

Android SDK+Ant

FindBugs\PMD\Lint\...

JUnit

adb install軟體部署

以Android軟體開發為例

Submited Code by A君

產出軟體版本v0.1b

產出v0.1b檢查報告*註6

產出v0.1b測試報告*註7

Submited Code by A君、B君。*註4

編譯失敗,發送失敗報告給程式碼擁有者B君。*註5

Submited Code by B君

產出軟體版本v0.2b

產出v0.2b檢查報告

產出v0.2b測試報告

Day1 Day2 Day3

軟體建置流程

圖 1.6 Jenkins的使用範例

本書將會針對流程中不同階段的項目產出進行介紹並提供範例,讓讀者對 Jenkins

工具使用上有一個完整的輪廓。

註 4註 5註 6註 7

註 4 第五章將會介紹如何整合程式碼管理伺服器,並且設定每天可以進行版本建置,讓開發者 /專案管理者瞭解每個版本所新加入的程式碼有哪些變化。

註 5 第二章將會介紹如何整合程式碼編譯工具,以及如何檢視編譯結果。註 6 第六章將會介紹如何整合程式碼靜態分析工具並產出分析報告,讓開發者 /專案管理者方便檢視程式碼中潛在的問題。

註 7 第六章將會介紹如何整合單元測試並產出每次版本的單元測試報告,確保每次軟體演進的品質。