| 考慮將持續整合觀念導入實務運作時,若能透過研讀專業書籍來了解,也是有效方法之一 |
| 持續整合(CI)雖然強調的是作業自動化,但有不少的執行細節及習慣的養成,仍須由人來配合,並藉著管理制度來規範,並非全然依賴系統平臺。而《Software Configuration Management Patterns: Effective Teamwork, Practical Integration》一書,當時彙集軟體團隊開發的有效成功模式,著重在標準化的管理規範及原則,讓軟體專案管理者能有跡可循,期望讓不熟的人也能照本宣科、按表操課。
全書強調的基本精神就是所有作業都能予以自動化,以有效提升專案執行的效率。最重要的是將實作的細節一併讓讀者了解,包括如何利用工具來完成建構、安裝、部署等作業。除了讓讀者了解正確的建構作業觀念,強調如何逐步將自動化落實在專案執行。 全書內容,以建構、安裝部署、監測機制的自動化為主軸進行探討。建構部分介紹了軟體專案目錄結構的定義方式、如何以Ant工具來建構專案程式碼、定義專案所需的建構腳本、結合JUnit測試工具合併測試作業、設置排程建構的方式;在安裝作業上,亦介紹利用NSIS(Nullsoft Scriptable Install System)來設計你的安裝程式(Installer);而在安排部署時所發行的版本,與開發測試時的內容有所差異,這本書也向你說明了,如何透過定義建構腳本的方式來包裝發行版本。 書中以CruiseControl為持續整合平臺為主要解決方案,加上各章節中均依主題搭配Ant腳本範例,可讓讀者快速定義自己的建構腳本檔,導入專案所需的自動化工具。其中部分自動化程序是作者撰寫shell script達成,書中亦直接提供程式碼。 由O’Reilly公司所出版的《Practical Development Environments》一書,則強調建構SCM核心觀念,內容經歷數項成功專案及數個不同開發團隊,適用於不同規模的專案上之實務證明,歸納出本書精華。書中亦提到不少建置自動化開發環境所需工具,讓你可將開發流程的各個環節緊密相扣,讓重覆枯燥的作業程序,透過系統正確並及時執行。 除了介紹軟體開發生命周期的各階段所適合導入的工具外,整個團隊各個角色的扮演,及達到良好的協同合作溝通,更是讓軟體專案成功的主因。 其中的一個章節闡述了人文與政治面的顧慮,像是具備程式碼更動權限的妥善分配,開發人員心中的真正想法,以及團隊紀律的要求等。作者依照過去專案經常發生的狀況提供具參考價值的建議。這樣的問題勢必存在,但能透過良好的互動預知可能的潛在問題發生,亦能降低專案風險。 持續整合的實作 軟體工程學界大師Martin Fowler 2006年時,再度發表Continuous Integration新版論述(http://martinfowler.com/articles/continuousIntegration.html),文中已將持續整合在實作上應該著重的原則,規範得相當清楚,後續在此議題討論的文章,都幾乎將這些原則奉為圭臬。大師的領頭羊效應後,業界陸續對觀注及討論這議題,不少書也開始雨後春筍般出現。 2007年Addison Wesley出版的《Continuous Integration: Improving Software Quality and Reducing Risk》,便是首本以持續整合CI這個名詞為標題的專書,其談論內容的完整度,筆者認為,算是歷年來相關書籍中寫得最好的一本。 本書先介紹CI時空背景及理論規範的演進,再逐步說明如何建立屬於自己的CI系統環境,兼顧理論與實務。作者先讓讀者了解過去開發團隊所面臨的痛苦及風險,掌握持續整合導入時所影響的作業層面,以及主要可解決的核心問題為何。一旦清楚導入的動機及效益後,再分章節介紹而建立CI系統環境所涵蓋的範圍以及組成元素。在介紹每個章節主題時必然搭配導入工具的設計方式,或是需要撰寫的程式代碼亦同步提供,讓讀者更能了解實作方式。像是如何以TestNG工具來撰寫單元測試程式,以及如何將這些任務定義到Ant建構腳本檔中。 而在書末附錄中,作者亦分門別類地整理了與CI有關的相關資源,並提供不同CI解決方案的評估選用考量要點。對於想開始導入CI的讀者而言具有甚高的參考價值,若你對持續整合完全沒概念,本書可以視為打好基礎的入門良書。 資料庫端的CI作業 當然持續整合的應用不只是在主程式的部分,現今應用程度絕大多數都與資料庫有關,跟隨著軟體版本的演進,資料庫的持續整合作業也不容忽視。《Recipes for Continuous Database Integration》,則是著重在資料庫端的持續整合程序,所有的資料庫相關的程式腳本均必須列入版本控管,才能讓程式碼與資料庫的組態一致。而在重複建構及自動化測試程度的進行過程中,對於資料庫的物件及綱要重建、測試資料之清除及準備、主程式版本升級時,對於現有資料庫結構的更新方式,這裡都有專文討論,而本書列示的十五項法則亦能讓讀者在進行資料庫整合自動化時能更順暢。 可協助CI的工具 工欲善其事,必先利其器。O’Reilly出版的《Java Power Tools》一書,對於開發作業過程中所需的工具有著詳盡的介紹,將絕大部分持續整合會用到的開放源碼工具,來個大閱兵,對於想嘗試持續整合實作的讀者,可以省下不少工夫。 書中所涵蓋的包括:建構工具Maven及Ant,版本控管工具Subversion及CVS,CI Server提到了Continuum、CruiseControl、LuntBuild、Hudson,自動化測試工具JUnit、TestNG、Cobertura,整合及效能檢測工具StrutsTestCase、DBUnit、JUnitPerf、JMeter、SoapUI等,軟體品質工具Checkstyle、PMD、FindBugs、Jupiter、Mylyn,問題追蹤工具Bugzilla、Trac,還有技術文件產生工具Doxygen、SchemaSpy等。這些工具的介紹,必然都會提到與建構工具的整合方式,例如定義Ant及Maven的建構腳本內容,讓自動化建構更能多元化,工作更簡單有效率。 與IT管理接軌 2010年Addison Wesley所出版的《Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation》,亦引起大迴響。本書中除了提及原本持續整合流程中的各個階段所應著重的原則外,更將考量層面擴大到系統維運階段的服務持續供應,必須達到系統服務不中斷的生態平衡。尤其現今的系統複雜度及規模甚高,企業因系統錯誤或問題所造成的損失及代價已不可同日而語,必須有效縮短軟體製程,在最短的時間內快速發布並修復更新來因應,以提升客戶滿意度,這已是現今企業所面臨的重大挑戰,相當值得管理階層一看的書。書中同時提及呼應ITIL中Continuous Delivery所考量的要點,提供了良好的實踐方案以遵循ITIL的本質,所衡量的標準亦能有效被滿足。 由於理論基礎持續成熟,業界採用搭配工具的程度也逐漸提高,像是Hudson、Maven、Subversion等技術手冊,也開始大受歡迎。Manning的In Action系列書籍,亦能提供讀者針對單一工具去獲得深入淺出的理解。 林林總總提到了這麼多書籍,透過閱讀較能完整取得此領域的知識,直接拿現在進行的專案來開刀吧!實際運用收穫更多喔! |
2011/07/14
2011/07/14
| 當完成建構及測試自動化,若欲進一步提升軟體品質等級,還有那些作業是可以接續落實的? |
要提升軟體品質,可從系統及人文兩個層面來要求:系統面以透過完整的檢測及掃描來確保測試的完整性,而人文面則是透過系統化文件的產出,以及良好的程式碼撰寫風格來讓可讀性提高。 前兩回文章所提到的建構及測試自動化,若都能落實在作業程序中,則軟體開發80%的自動化需求大致底定。一般而言,只要能先確保軟體功能正確無誤,行有餘力才會再來求品質的提升。就實務而言,由於時程及人力資源條件的限制,僅著重於功能驗證無誤,即安排版本發布及上線程序,品質強化的部分反倒甚少被重視,然而許多問題在未來系統正式上線後,在使用度及資料量的日益成長之下逐漸浮現──很多都是由這些潛在的品質因素所引發出來的。然而開發的系統時間一久,功能範圍日益擴增,加上開發人員的職務異動,程式碼本身所包含的資訊,是否足夠讓維護接手的人員不中斷地持續開發作業,在文件及程式碼的可讀性即為關鍵性因素。
未雨綢繆、及早預防──程式碼靜態掃描 所謂靜態程式碼掃描,主要用意在於透過問題模式比對的方式,對於已撰寫好的程式碼進行錯誤的先期預防,以及早避免曝露可能的系統弱點,或是隱含的系統錯誤及效能問題,而降低系統上線後才發現問題的風險。多數軟體品質的問題,可以從程式碼的撰寫方式來推出潛在可能引發的問題,而且有許多工具累積了不少問題模式及類型(bug patterns),在執行掃描的過程中便能逐一列出問題的所在。 像是常見Null Pointer Exception的發生可能性、無謂變數的宣告使用、過於複雜的邏輯判別式、重複多餘的程式碼內容、關於密碼變數值的管理方式,或是程式碼可能造成SQL Injection被入侵,及跨站腳本攻擊(XSS)的疑慮等。 這樣的掃描作業,當然也能整合到建構自動化的設定中,在每次建構完畢即產出靜態掃描的結果報表供管理者參考。所發現的問題,會依你所採用的工具,而有詳細程度上的差異,這些問題也會依重要性來分類。而管理者則視其必要性,決定是否列入修復的必要項目。 較常被採用的免費開發源碼工具,像是Findbugs、PMD等,商業套件像是Parasoft、Fortify等,其所著重的掃描問題重點及類別,都有所差異,原則上都可支援與既有的開發環境,並提供與建構工具(像Ant、Maven)密切整合的功能,方便併入建構自動化程序中。像Fortify甚至提供專家知識庫,針對不同問題提出建議做法,協助開發人員進行改善作業,提升不少工作效率。 撰寫程式即撰寫文件 實務上,通常都是開發完畢後,才挪出時間後補文件的撰寫,做為專案驗收的依據,而且,日後文件持續維護的工作並沒有落實,長時間下來,文件的價值也就被忽視。程式即文件的觀念,早在倡導敏捷製程時,就已經被強調,期望開發人員在撰寫程式時,一併將應註記的內容填入,保持內容的可讀性。 自己撰寫的程式若未附上良好的註記說明,一段時間再回頭來修改,常需要花上較長時間了解程式原意,更何況是轉交由其他非原開發者維護,這樣的問題會更加嚴重。若你用Java程式語言開發,透過Javadoc工具,即可自動化產出可供技術開發人員參考使用的文件,應用簡單的撰寫原則,可在開發過程中同步註解程式碼提高可讀性,降低未來維護時重新修改所需投入的成本。 而除了Javadoc產出的API類型文件之後,亦有其他圖形化文件產生工具,讓文件內容的可讀性更高。像是Doxygen、UMLGraph,可依程式原始碼反向產出UML圖表,提供基本的Class Diagram及Collaboration Diagram,來表示其物件階層及相依性,讓開發人員在未經手程式碼之前,透過閱讀圖形化文件先掌握系統全貌,不致於發生直接閱讀程式碼,有見樹不見林的問題。 而SchemaSpy,則是針對資料庫端所提供的文件自動化產出工具,依照目前資料庫中已經建立的物件結構,進行反向工程文件產出,依table、view、relationship、constraint等常見的內容,予以系統化列出,並以E-R Diagram方式,表現資料表之間的關連性──只要在建立這些物件時,一併撰寫備註文字,像是資料表及資料欄位的說明文件,在這裡的文件都能被清楚呈現出來。由於此工具是利用JDBC方式與資料庫連接,它可支援目前業界大多數的資料庫產品,相較於知名商業軟體像是CA的Erwin Data Modeler、Sybase的PowerDesigner和Toad Data Modeler等,不需付出高額成本,即可產出專業化的資料庫規格文件。 這些圖形化文件的優點在於,方便將Diagram與程式碼內容的瀏覽,合而為一,讓閱讀者在追溯物件關係並檢視到原始程式碼的行為上,更為流暢。所提供的文件格式,亦以HTML格式為主,支援全文檢索功能,閱讀者不需額外安裝特殊軟體即可瀏覽。 不過,上述工具雖然能協助快速產出圖形化的專業技術文件,但內容的充實與否,仍須落實平日開發人員的作業上──對於程式碼的註記方式,必須確實養成習慣及規範,否則產出的文件內容參考價值就有待商榷。 另外值得強調的是,這些使文件自動化產生的工具,只是單純輔助事後撰寫文件的效率提升,但針對像是需求規畫分析設計過程所產出的文件,並不會因此而省略掉。這些文件則是配合思考的過程而產出的規畫內容,切勿混淆。 一致化的程式碼撰寫規範 程式碼的撰寫風格一直是被討論的課題,許多原則早在昇陽電腦所定義的程式碼撰寫風格規範(Sun Code Convention)中提到,不外乎是希望每個開發人員能配合一致性的撰寫方式,讓後續維護工作的人員能快速接續處理而降低維護成本。 常見的規範,像是空白字元的數量及出現位置、變數的命名規則、Javadoc中所要求的註解內容必須填寫、程式檔頭的標準說明內容等。不過這樣的要求在實務上,的確不容易,開發人員習慣的程式碼排列方式,與其開發生產力有著直接的關係。此時就會考慮導入程式碼規範工具,來強制將代碼內容規格化。 常見的格式化工具,像是CheckStyle、Jalopy等,可以安裝在你的在開發環境中(像Eclipse),在撰寫程式碼時,編輯器便會在不符規範的程式碼的該行首位置,顯示警訊,即時提醒開發人員遵循規範來寫作,而規範的內容亦可由開發團隊自己定義,調整出適合既有專案開發團隊都可以接受的方式。 在每次建構時,即可將程式碼依指定的規範格式進行內容檢查,或是在CI Server上進行建構自動化程序時,將整個專案的程式碼一併處理,並可強制設定當不符合規範時,即中斷建構作業。規範的嚴重程度,亦可以自行定義。 規範的定義在實務上,也不要太過強硬,導致妨礙整個建構作業的流暢度。畢竟撰寫規範的落實並非必要條件,建議可以先以Jalopy,將程式碼自動調整成期望的格式,再以CheckStyle進一步確認,會更為可行。 實務上,開發團隊常因方便行事,而一般客戶在需求規格中亦甚少提及針對品質部分進行要求,或是將此課題視為非必要性的。軟體品質的提升非一蹴可幾,自動化工具僅能輔助,更重要的需管理者的重視,以及全體開發團隊的配合施行,才能達到應有的水準。 |
2011/07/14
| 當建構自動化作業整合到CI伺服器時,為提升軟體品質,接下來便是落實軟體測試作業自動化 |
|
要達到持續整合中所提到持續且不斷改善,沒有理由不利用自動化方式來進行這些重複且標準化的作業。在《軟體測試之道—微軟測試團隊的成功經驗、方法與技術》一書中提到,光Office 2007這套軟體就包含超過百萬個測試案例,相信微軟工程師勢必結合高效率之自動化方式,才能在有限時間內完成這項偉大的測試工作。 記得中學國文課本的《指喻》,意謂著問題修復的成本會因時間歷程愈久而愈高。測試自動化作業便是以化整為零的概念,將過去開發階段所獨立定義的測試階段,打散部分的工作提前到開發建構階段來處理,早期發現早期治療。 要落實測試自動化,接下來必須面臨的現實問題就是需要撰寫額外的測試程式。直接反應到開發人員所需要額外花費的工時。然而實務上常因時程與人力不足的現實限制而讓測試程式碼的撰寫大打折扣,進而讓測試作業無法發揮測試應有的效益。 對於測試程式的撰寫方式,大多是將主程式的元件及服務都撰寫完畢後,再來撰寫測試案例。實務上常會因為時程的壓縮造成撰寫測試案例的時間被省略掉,以致未能達到良好的測試。敏捷(Agile)製程中的測試導向開發(TDD),則是強調先撰寫測試程式,再逐步衍生出主要的核心元件及服務,不斷地改寫原本的主程式來符合測試程式的結果。 是否採用TDD引起不少討論,就筆者面臨的實務經驗及現今企業的組織分工狀況,不見得能順利落實。像是具有專責測試人員或單位編制的企業,其主程式與測試程式的開發人員不是同一人時,就不易進行先測試再寫主程式代碼的方式。 然而開發工具的支援也是相當現實的問題,像目前微軟Visual Studio 2010可支援撰寫測試程式的當下,同時產生尚未開發的主程式類別屬性及方法,就更能貼近TDD的想法,否則只是讓開發人員因為測試無法進行而又回到原始做法。 軟體測試型態及使用時機 在軟體工程中所定義的軟體測試類型的種類繁多,但就實務上因專案時程與人力資源的限制,通常會選擇重要且必然被重複執行的項目來要求。 ● 單元測試(Unit Test) 是針對單一元件本身的設計進行測試,以確保最小單位的處理邏輯是正確無誤。檢測方式主要是針對元件提供的方法進行輸入及輸出的驗證,以確保內部處理邏輯的正確性。就單元測試本身的特性是輕薄短小,為了發揮物件化設計的精神,高內聚力低耦合力的元件架構下,單一元件的測試作業是相當輕快的。而這個測試的執行可以整合於建構平臺中,每當有任何程式被異動交付(commit)時隨即進行,可及時檢測。 ● 功能測試(Functional Test) 它會結合多項元件針對特定功能聯合檢測,範圍會是著重在特定子功能模組或是,其測試步驟可能會有前後相依性,單一測試案例的時間及複雜度都較單元測試為高。視情況在CI伺服器上設置定期排程方式,進行自動測試作業。 ● 系統整合測試(System Test) ● 迴歸測試(Regression Test) 可以避免既有功能因新版本的釋出而發生錯誤。軟體功能相依性無法完全避免,程式碼只要異動,可能會引發連帶影響,若能在異動當下即能確保相關功能是否通過測試檢驗,由於功能因版本變更而持續增加,這部分的測試程式亦是不斷累積日趨成熟,可被持續重用,除非原本功能及處理邏輯已被異動。 ● 效能壓力測試(Performance and Stress Test) 針對主程式在上述相關測試工作都已經完畢,結合正式環境或擬真環境來進行系統效能及壓力承受度的檢測。此類測試的結果會因系統執行環境的狀況而有不同結果。一般而言是針對每個測試案例或測試計畫來統計平均需要花費的時間有多少,供管理者評判該數值的合理性;而壓力測試則必須以正式環境,所得數據才有參考價值。 ● 測試涵蓋度的監控 (Coverage) 因為軟體功能的日益強化,相關測試程式的數量也是不斷增加,就測試範疇多少會有漏測或是重覆測試的情況出現,搭配測試涵蓋度的工具來同步監控,能清楚掌握主程式被實際測試的廣度及深度為何,進而調整測試程式內容。選用的涵蓋度監控工具必須與你所採用的測試框架能整合互通,才能發揮效益。 測試自動化的實務規畫設計 在撰寫測試程式時如何運用良好的設計思維,來讓繁雜的測試程式代碼更易於使用及管理? ● 既有開源資源的引用 針對軟體測試的開源框架已經相當成熟,因應不同測試領域而有多種成熟的解決方案可供採用。這些框架容易學習便於上手,亦提供完整的測試結果報告。常見的像是著重在單元及功能測試的JUnit、NUnit,針對資料庫存取進行資料驗證的DBUnit;運用在Web Server測試,檢證XML資料格式的XMLUnit; 模擬瀏覽器操作行為,針對網站應用程式測試的Selenium;還有,HTTP通訊協定測試的HttpUnit、針對J2EE應用程式整合測試的Cactus、提供效能及壓力監測的JMeter、JUnitPerf,以及測試涵蓋度監控的Quilt、Cobertura,與程式碼靜態掃描的Findbugs、Lint等。 ● 測試程式獨立規畫 原則上針對主程式所撰寫的測試程式,亦會依照所測試標的及類別,分別以不同的套件package及類別class來設計撰寫,而不混用在現有的主程式之中,以便於因為不同建構階段執行不同測試自動化內容,及整合建構自動化之管理。例如會以獨立命名一套package;而每個測試案例亦必須都能單獨運作,減少測試程式之間的耦合程度。 ● 測試程式代碼的快速產生 不管你是用何種方式來撰寫測試案例,運用良好的測試框架,結會既有開發工具來輔助測試程式代碼的快速生成是相當重要的。由於撰寫測試程式的代碼實屬枯燥粗活,若可妥善利用程式碼產生工具亦可協助減少撰寫所耗費的時間。例如利用Eclipse IDE內建JUnit plug-in建立單元測試元件;WTTools開源專案裡的UnitTestGen,可整合在建構腳本中自動化產生JUnit對應測試程式碼,並同時進行單元測試作業;商業軟體Parasoft亦針對不同程式語言提供像是JTest或c++ Test等工具以利輔助。 ● 彈性設計方式,減少修改的頻率及幅度 由於主程式的不斷發展,測試程式亦得隨之更動測試內容及測試範圍,新增了一個方法,修改了一個傳入參數,對應的測試程式都很再調整,如此一來暴增的工作使得開發及測試更無法兼顧。像是利用Java Reflection的方式,在測試案例的撰寫時自動找尋應測之方法有那些而逐一檢測,或是導入類似OpenPojo測試框架來處理單一pojo或entity物件的測試,亦能單純化測試程式的撰寫。 ● 與持續整合平臺無縫結合 已撰寫完畢的測試程式,不是只單純利用IDE方式執行即可,最終需要結合CI伺服器平臺,依實際需求來決定各項測試作業執行的時間點,可支援指定排程自動啟動(Scheduled Automation),程式碼交付即自動啟動(Trigger Automation),並針對測試結果即時透過通報機制分派問題及修復錯誤,如此才能真正做到持續整合的精神。 |
2011/07/14
| 了解良好版本控管機制的評估及導入注意事項後,本回接續討論持續整合的核心主軸: 建構自動化
|
| 持續整合期望以集中化的管理平臺,將專案開發過程中所有資訊都能統一控管並透明化,針對建構作業的部分,能提早發掘出整合時會面臨到的問題,進而及早解決,所以將建構予以自動化(Auto-Build)則是落實這想法的重要原因。
● Validate:確認專案編譯所需資訊,以及相關準備項目均已正確無誤。 ● Compile:編譯專案程式碼。 ● Test:將編譯完畢的程式,結合指定的測試框架進行單元測試。 ● Package:將編譯完畢的程式相關檔案進行封裝,例如產生JAR檔案。 ● Integration-Test:將封裝完畢的套件部署至測試環境,進行整合測試作業。 ● Verify:驗證封裝完畢的檔案,品質符合要求。 ● Install:將封裝的檔案安裝至本地儲存庫(Local Repository),做為其他專案相依性的參照使用。 ● Deploy:在整合測試完畢後,將可部署的版本發布至正式環境 你可依所需搭配建構指令,將這些階段依序進行。目的在於將專案相關的程式碼編譯且封裝成可部署的套件,並完成正確性及品質提升的整合。實務上你只要決定需要的部分,再予以自動化。 建構自動化對既有作業的影響 利用系統設置排程來自動建構,除減少人工介入時間,結合「盡可能持續交付可成功建構的程式碼」,就能夠及早發現整合建構時可能失敗的問題,而立即處理解決,進而降低在整合測試的風險。 而專案經理或技術主管則不需要再手動進行建構及部署指令,這些繁雜的指令都改由系統自動代勞。利用持續整合平臺的機制,依建構自動化的結果來決定是否需要緊急處理。CI伺服器記錄每次建構作業的狀態及細節,可提供開發團隊成員透過Web介面方式即時查得,亦能依建構結果即時通知以利及早處理。 建構自動化設計的多維度思考 就建構作業而言,不僅是將程式碼編譯封裝完成即可,在實務需求上仍需面臨多種維度的思考,才能使建構平臺的優點發揮極致。 ● 針對不同作業環境的需求 因應開發流程中所需的不同環境(像是開發環境,測試環境,正式環境等),以一致性的建構平臺機制來處理,來產出不同的建構結果(像是private build、integrated build、release build),減少重複建置所引發的管理問題。 利用一致化的組態定義檔來決定各種環境建構作業的細節,實務上最常見的就是不同環境必須參照不同的屬性檔(properties),其中包括了資料庫環境(測試與正式環境分隔),內部其他系統(如:ERP),外部介接系統(如:金流付款閘道系統)相關連線參數的對應;另外在不同環境之建構作業,其內容亦會有所差異。例如,在開發測試環境的建構作業會完整執行單元功能測試的測試計畫及案例,而正式環境則會免去此作業。 ● 針對不同任務目的的需求 建構作業除了最基本的編譯封裝成二進位檔之外,為提升軟體品質,可利用建構腳本將其他任務一併加入建構作業中,例如單元功能測試、測試涵蓋度檢驗、靜態程式碼安全性檢測、程式碼內容撰寫規範及文件產生器等。這些作業只要是程式碼一旦異動,就應該重新再次執行確保內容符合規範。 ● 針對不同專案範疇的需求 好的建構平臺可以依不同專案定義出對應的建構計畫,而這裡的專案亦可直接對映到版本控管工具裡的專案定義,前後整合更易管理,對於開發團隊的溝通亦比較有效。 而建構平臺的彈性與選用的解決方案有關,較知名的像開放源碼常用Hudson、CruiseControl,商業解決方案像Microsoft Team Server、IBM Rational Team Concert、Parasoft Concerto。 ● 建置你的持續整合平臺 首先,你需要一個獨立作業環境來安裝CI伺服器平臺,以避免此平臺的運作影響到其他服務的正常運作。Hudson應屬業界採用度最高之免費建構平臺,其安裝快速,系統設置容易,同時提供甚多的延伸外掛工具可供選用,可讓你快速建置持續整合平臺及其他整合機制。 其中不乏知名開放源碼解法方案,像版本控管的Subversion、專案管理的Maven、建構機制Apache Ant、測試框架JUnit等。 建構自動化要能發揮效益,接下來便是了解建構腳本(Build Script)的定義。建構腳本的想法延伸自早期Unix系統中的makefile,透過編輯這樣的檔案內容,來決定編譯的方式及程序為何。然而現今的建構作業的需求範疇愈來愈廣,所有欲被執行的任務(task)均可被定義在建構腳本之中,而任務之間的關連性及先後執行順序,也能一併管理。 實務上最常見知名的建構工具非Apache Ant莫屬,而它同時提供外部函式庫版本同步控管,能將專案所需使用的所有檔案版本均列入管理。 每次的建構作業,都會詳盡記錄每次版本更動的內容,可以清楚查得建構結果,以及該次建構作業包括了那些異動內容。 建構自動化與其他流程之串連 一旦建構自動化平臺建立後,可透過其管理介面來設置與其他機制的整合方式,常見需要串接的系統主要有: ● 版本控管工具。建構平臺會針對欲建構的專案,從版本控管工具(如CVS、Subversion)的儲存庫中,取出程式碼,之後進行建構。而建構可依時程啟動或程式碼異動即啟動。 ● 整合性報表及通報機制。建構作業的結果必須能被清楚及有效地被開發團隊所知悉,所以良好的報表及通報機制是CI伺服器平臺所必備的。一般建構平臺會依其定義的任務,產出對應的建構結果報表,亦可設置條件進行通報,藉由電子郵件或RSS訂閱機制來通知相關人員。 ● 自動化測試工具。軟體的品質是透過不斷測試而持續提升,但測試工作是繁複且費時的,型態及種類繁多,實務上在有限時間及資源下,能做到一定品質的要求,我們將在下回探討。 ● 問題追蹤管理(Issue Tracking)。開發團隊常會以這類工具來管理軟體錯誤問題,知名的像是Mantis、Bugzilla、Trac等。由於建構作業的持續,每當發現問題都必須及時追蹤跟進處理。可將建構作業的狀態的更新資訊整合到問題追蹤系統頁面中,或是將建構資訊中的備註內容提供連結,依問題編號連到問題追蹤系統的對應內容以便參考。 ● 與應用伺服器間的整合。若同時希望在建構作業完成後,直接進行部署至應用伺服器上,供後續使用者接續測試,則可定義自動部署的任務。目前的CI伺服器可結合多種應用伺服器。 ● 與資料庫伺服器間的整合。若你的軟體專案需要操作資料庫,資料庫環境的建置亦可整合至建構作業之中,在建構作業前期,CI伺服器會到版控儲存庫中取出目前資料庫DDL及DML的相關script,每次的建構都會依此內容重新建置資料庫,以確保程式碼與資料庫的定義一致。 所以建構自動化可達到「一指定江山」,以往繁瑣分散的動作都整合執行,工作效率當然提升。 |
2011/07/14
| 版本控管(Version Control)是落實持續整合工作的源頭第一站
|
| 在軟體開發過程中,程式碼的保存一直是不容忽視的工作事項,而這常受到許多不可抗力因素影響,像是硬碟故障、檔案被誤刪或覆蓋,而造成事後甚高的補救成本。
人有失足,馬有亂蹄,因為程式總會寫錯,需求規畫也可能隨時變更內容,所以,系統總是會需要回復到先前開發的版本。
而為同時能方便維護,版本控管工具也提供了軟體分線管理的概念,讓軟體的管理者可以依特定需求在同一時間發展不同的軟體版本,而將彼此的影響程度降到最低。 另外,軟體開發通常需要多人協同運作,此時就會團隊運作必須解決同一份程式碼同時被多人編輯的問題。版本控管工具提供了成熟良好的機制,發出警訊提醒管理者及相關開發人員及早處理,以避免未預計的狀況不斷發生而延誤開發時程。 版本控管在做什麼? 一般版本控制軟體的系統架構,以集中式管理為主,而且,系統會以儲存庫(Repository)的方式,將所有欲被控管的檔案內容保存下來,包括在開發過程中所有對程式碼的新增、修改、刪除等動作。 軟體開發人員透過簽出(checkout)的方式,取出指定版本的程式碼內容,在開發環境針對自己的程式碼修改驗證無誤後,即可利用版本控管軟體將修改的程式碼檔案交付(commit)到儲存庫中。一旦交付,版本控管平臺會自動賦予一個修訂版本編號(reversion),做為未來版本管理的主要鍵值。 版本控管平臺允許用專案(project)的方式,來分別定義管理不同範圍的程式碼,而開發人員依其權限的設定,可將指定專案的程式碼內容更新(update)至自己的工作環境(workspace)中,開發者在交付程式碼內容時,版本控管工具會依版本編號來判斷是否可以直接交付,或是出現版本內容衝突(conflict)的警示,讓開發人員進行後續程式碼內容比對(diff)及協調處理。 版本規畫的實務運用 版本控管工具都支援版本標籤(tag)及分支(branch)的機制,以利管理者在軟體發展的生命周期中方便管理。 這兩種方式的使用時機如下: 當軟體開發至可部署發行的版本(release)時,此時就會以標註tag的方式,以利未來快速調出版本內容。標籤的命名方式可結合日期,版控工具的trunk/tags/branches層級編號,對外發布的版本編號,主要發布功能,或是問題編號等資訊以利人為判讀。 然而分支的運用,常見的實務運用像是自有軟體產品的公司,會有預定的產品發展計畫。而實際導入在客戶端時,必然會針對客戶需求進行部分客製化調整,此時這個客製化版本即可利用分支的方式來後續開發管理。規畫出分支的版本,是可以不用再合併(merge)回主版本的。 另一種常見的狀況是同時進行多項需求平行開發時,彼此可能會因為修改在針對軟體加入新功能,而此功能之開發所需時間較長,擔心新功能開發過程中因舊功能發生錯誤需要修復而造成困擾。所以會將較費時的需求,規畫一套獨立分支版本,未來開發完畢再合併回原主版本。 程式碼的合併是有風險的,所發生的內容衝突都會造成不可預期的額外工時,包括了合併程式碼、測試驗證,甚至重新設計等。 相關工具與評估選用的考量點 從早期的CVS,廣泛採用的SubVersion,以及最近較常被討論的Git等,都是活躍於開放源碼界、常用的方案,若你考慮付費的平臺,像IBM Rational Team Concert、Microsoft Team Server等,亦包含版本控管的產品線。 而選用的考量上,有以下幾點: ● 是否與目前開發團隊的開發工具無縫整合? 版控的相關功能必須要能整合在現有的整合性開發環境(IDE),若在開發過程中切換多個視窗,來處理頻繁的程式修改動作,不易提高工作效率。 ● 版本控管平臺是否支援Web介面操作使用? 除開發人員會透過client工具直接存取,若平臺也提供Web介面提供相關資訊,非開發人員想要了解內容則可以不用再安裝工具,可直接用瀏覽器的方式查看,應用上會更方便。 ● 管理上的方便性? 由於大部分版本控管系統採集中化方式管理,當將所有的專案都往上頭一一建置後,其扮演的角色就日益重要。在可用度及備份機制的完整性上也必須一併考量。 另外,由於近期雲端概念的盛行,也可考慮採用既有的服務提供平臺來處理軟體版本控管的需求,除了提供可存取性外,也能節省實體硬體設備及平臺維運的成本。知名的像是Sourceforge、Google Code、github、BerliOS Developer,都有類似服務。 ● 是否支援其他理論規範? 像CMMI、ITIL、PLM等,大型企業已經逐漸重視,視為企業流程標準化的參考依據。若公司已經計畫導入類似的作業流程,所選擇的解決方案必須要同步考量是否滿足這些規範的需求才行,否則屆時可能會面對系統重新移稙的成本。 ● 是否支援多站點架構(multisite)? 實務上常見以外包方式進行專案開發,甚至外包對象會是跨企業,甚至跨到對岸去,所以版本控管的架構是否能有效支援多點管理,其中針對不同站點之間的資料複寫及同步、權限控管,都很重要,而且它們都是十分複雜的機制。 除了導入工具,專案團隊還需要…… 系統只是個協助存取程式碼的工具,然而當軟體開發團隊欲應用在實務上時,有一些良好習慣的養成及作業規範,是必須先形成共識的,例如: ● 當開發者接獲需求欲開始進行開發前,必須先利用版本控管工具,取得目前儲存庫中最新版本的程式碼內容再開始作業。 ● 只要開發者撰寫程式碼到一個階段,就將可建構的版本隨時交付至程式儲存庫中,並落實log註解內容的撰寫,以保持儲存庫中的程式碼是最近狀態,且是可被成功編譯建構的。 ● 在交付程式碼時當發生與現有版本內容衝突的情況,從修改歷程記錄中得知前一版修改人員,進而主動與其討論解決。 ● 開發人員每日下班前,必須將工作環境中可建構的版本交付出來,千萬別將程式碼保留在簽出狀態,人就下班了,相信當遇到程式碼內容衝突時,不在場的人常是犧牲的對象。 ● 結合自動化建構工具的整合,專案經理在得知建構作業發生錯誤時,必須立即通知相關程式碼負責人員一起處理即時修復,以利開發作業能持續進行。 我認為,這些規範的落實比選用那一套版控工具要重要得多,故在評估導入時必須強化宣導,否則持續整合之價值無法有效彰顯。 最後,你只要思考一個問題:當正式版本軟體因不可抗力之因素無法取得,或正常運作,是否可以從現有的版本控管平臺,重新完整建構一份出來完成系統復原作業,你就會知道要應將那些內容納入控管。 |
至於2004年Pragmatic所出版的《