程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 為什麼要做持續集成,要做持續集成

為什麼要做持續集成,要做持續集成

編輯:JAVA綜合教程

為什麼要做持續集成,要做持續集成


持續集成在目前大多數的公司裡都會有這樣或者那樣的使用。有的會選擇一些Open Source的工具,如CruiseControl,Hudson,LuntBuild等等等等,有的會購買有更好服務,更強功能的商業產品,如TeamCity,QuickBuild等等,而有的會選擇自己實現,如Cron+Ant/Maven/Make等等。那麼使用下來效果如何呢?真得達到了預期的效果嗎?我想來恐怕未必吧,否則也就不會有這麼多的討論了。[@more@]

持續集成與敏捷編程

在敏捷領域中,測試驅動和持續集成被稱為敏捷編程的兩大基石,於是乎,很多人的概念裡就是持續集成是為了實現敏捷編程的。這是一個錯誤的認識。實際上,早於敏捷編程概念的提出,持續集成作為一個best practice就已經被很多公司采用了,只不過作為一個概念,則是由Martin大叔為了推進敏捷所倡導並由此風靡起來。持續集成本身只是一種practice,並不被什麼開發模型所限制,在任何一種開發模型中都可以采用,也可以運行得非常理想。

持續集成還是階段集成

有很多人說,我不做持續集成,照樣工作的很好。因為我們一個(小)階段出一個版本,照樣控制得非常好。我得恭喜你,首先持續集成也好,階段集成也罷,你做了,做了就好,比沒有做要好很多,也使你的項目管理上了軌道了。這兩者之間的區別僅是頻率而已。

那麼究竟那種方式更加理想,更加符合項目的開發和管理呢?其實這個問題Steve McConnell在他那本獲得Jolt大獎的書《Code Complete》(代碼大全)裡有過回答了。他說:對於一個微型程序來說,階段式的集成或許是最佳方法。何謂微型程序,他說就是那種兩三個類的程序,而你又很走運的話,那麼階段式集成就可以是你的最佳方法了。當然,這位老兄是個老美,我們也都知道老外嘛,都比較笨一點,所以呢,他說微型程序,對於我們擁有5000年文明的中國人說,可以再擴大點吧,對於一個小型項目,就是那種二三十個類的項目,也許使用階段集成也不會出啥子問題吧。不過,你要真的是懶到連個階段集成都不願意做的話,那麼你至少求求上帝保佑你的項目一切順利。

為什麼要做持續集成

很多人肯定非常不苟同我的看法,他們認為即使沒有做持續集成,甚至沒有做階段集成,但是項目一樣按時的完成,甚至提前完成,而且照樣完成的非常理想,老板滿意,客戶滿意。而做持續集成,無非就是動不動收到一封郵件,說這個build成功了,那個build失敗了,不過就是一持續編譯罷了,我自己打個命令編譯一下,不就知道了嗎?要做個daily build,我還要去set up,還要花力氣去配置,效果也不見得好到什麼地方去。

對於這樣一些問題,我想首先我們還得搞清楚,究竟為什麼我們要去做持續集成,持續集成究竟可以給我們帶來什麼好處。同樣在《Code Complete》裡提到了,對於持續集成(在書中,Steve McConnell使用Incremental Integration的術語)有以下幾點好處:

易於定位錯誤。也就是當你的持續集成失敗了,說明你新加的代碼或者修改的代碼引起了錯誤,這樣你很容易的就可以知道到底是誰犯了錯誤,可以找誰來討論。
及早在項目裡取得系統級的成果。因為代碼已經被集成起來了,所以即使整個系統還不是那麼可用,但至少你和你的團隊都已經可以看到它已經在那了。
改善對進度的控制。這點非常明顯,如果每天都在集成,當然每天都可以看到哪些功能可以使用,哪些功能還沒有實現。如果你是程序員,你不用在匯報任務的時候說我完成了多少百分比而煩惱,而如果你是項目經理的話,那麼你也不再煩惱程序員說完成了編碼的50%到底是個什麼概念。
改善客戶關系。理由同上。
更加充分地測試系統中的各個單元。這也是我們常講的Daily Build與Smoke Test相結合帶來的絕大好處。
能在更短的時間裡建造整個系統。這點恐怕要你實施以後才能得出結論。就我們而言,持續集成並沒有為每個項目都縮短時間,但卻比沒有實施時,項目更加可控,也更加有保證。

隨著時間的推移,持續集成帶來的更多好處,也逐漸被認識到了,比如說:
有助於項目的開發數據的收集。比如說,項目代碼量的變化,經常出錯的Tests,經常出錯的source code,等等。
與其它工具結合的持續代碼質量改進。如與CheckStyle, PMD, FindBugs, Fxcop等等等等的結合。
與測試工具或者框架結合的持續測試。如與xUnit,SilkTest, LoadRunner等等的結合。
便於Code Review。在每個build裡,我們都可以知道與前一個build之間有什麼改動,然後針對這些改動,我們就可以實施Code Review了。
便於開發流程的管理。比如說,要把一個開發的build提交給測試組作測試,測完滿意了,再提交到發布組去發布。

怎麼做持續集成

持續集成有很多很多的好處。可是持續集成要做好的話,本身就有很多的講究。從持續集成工具的選擇到持續集成具體實施,每一點都可能影響到你使用持續集成的效果。持續集成不是持續編譯,也不是僅僅用來發發郵件的工具而已。

工欲善其事,必先利其器。首先選擇一個好的工具很重要,在我另一篇帖子《持續集成工具的選擇》中,我已提到過了,這裡不再多說。用下來,我覺得QuickBuild真得很不錯。

工具選好了,具體怎麼做呢?這個沒有什麼標准可以遵循,每個項目都是不一樣的,我談談我們這裡的具體過程吧。

首先,我們對編碼有一些規范需要遵從,所以我們制定了一系列的FindBugs和PMD的規則用於檢查代碼。
其次,我們使用Cobertura作為我們的代碼覆蓋(code coverage)工具。
再次,我們使用JUnit作為我們的unit test工具
基於上述幾點,我們編寫了我們的Ant腳本,這個腳本有一系列的task,基本上就是:
compile, source code analytics, unit test, generate reports, generate javadoc, package artifacts

這個,也是Java領域中經常使用的一個完整的過程。

有了這樣一個腳本以後,我們開始配置我們的項目到QuickBuild中去,在QuickBuild中,我們配置一個configuration,然後設定我們的SCM repository,對應於我們的ant task,我們配置了一系列的step,用於完成整個過程。由於我們的測試需要跨平台,所以對應與同一個unit test的task,我們使用QuickBuild的分布式的step功能,使之在不同平台上可以進行測試,這一點也是使用CI Server的一個好處吧。

對應於這個configuration,我們配置了四個子configuration,分布是Development Configuration, QA Configuration,Integration Configuration和Release Configuration。這幾個configuration分別對應於我們開發過程的四個階段,我們的每日構建都是在Development configuration上的,所以我們配置為每日一次,而對於其它三個則不做自動的構建。因為我們是通過Promote來做的。對於Development Configuration,我們沒有對SCM自動打Label,而對於其它的,我們則對每一個Build自動對SCM進行打Label。

有了這些以後,開發工作開始了,我們每天的代碼在下班前都提交到subversion裡去,第二天,Development Configuration就自動的編譯完成了,並且發送通知給我們。我們通常會會開一個Morning Meeting,首先我們會到在QuickBuild的頁面上,看到昨天有哪些個改動,測試的狀況,比如說哪些測試修正了,哪些測試還沒有被修正,哪些source code沒有通過代碼檢查。然後我們會點到具體的報告中去分析,這些報告都可以很容易的打開source code,我們可以直接在上面對各個改動做code review。通常這個工程耗時約30分鐘結束。
經過這樣開發之後一段時間,我們的功能很多已經就緒,就可以提交給QA作test了,由於當日的構建可能失敗,或者不是我們特別想給QA的,那麼我們會選擇之前幾日的一個好的build做Promote,這個promote就會自動觸發QA Configuration去做build,QA Configuration的build做完以後,就會發送一個郵件通知QA Lead,這封郵件裡QuickBuild會把所有與上一個QA build的changes都列出來,這樣他就知道我們這個版本裡增加了什麼功能,修正了什麼bug。
再如此經過幾個迭代後,我們開發組和QA組一致認為功能基本實現了,bug也不多了,於是就由QA的Lead做一個Promote,觸發Integration Configuration不build一個大版本交給客戶,做VOC (Voice of Customer),聽卻客戶的意見,如果客戶沒有什麼易見的話,那麼就會在Integration Configuration上做一個Promote到Release Configuration上去。

通過這樣做,我們基本上可以很容易的知道每一個版本之間有什麼變化,甚至我們可以很容易的重新build出任何一個時間點上的版本。而且,我們基本上無需操心什麼時候給SCM打什麼樣的Label,因為對於我們而言,我們需要看到的只是每一個版本的build。而如果用subversion來管理的話,也許你也可以通過命令來列出在SCM中各個版本的變化,但是如果有一天,你頭昏忘記打label的話,或者打錯label的話,也許要找到這個問題就不是那麼容易了。又也許,你可以通過一系列的命令來完成這裡提到的所有功能,但是我覺得如果計算機可以完成的話,還是讓計算機去做吧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved