李興凱+曾東旭+陳敏



摘要:基于軟件開發中的測試需求,分析和研究持續集成環境問題,提出最小持續集成環境概念,并給出典型最小構成。對軟件開發各階段的不同測試進行可持續集成需求分析,指出多設備環境配置是其中最不穩定、最易出錯和最需要持續集成的。對4G LTE無線網絡的多設備環境配置需求及對持續集成工具的Web訪問局限性進行了分析,并在Jenkins平臺上實現了Web訪問的二次封裝。
關鍵詞:持續集成;Jenkins;自動化測試;Web訪問
DOIDOI:10.11907/rjdk.171128
中圖分類號:TP306
文獻標識碼:A 文章編號:1672-7800(2017)006-0011-04
0 引言
持續集成(Continuous Integration,CI)思想源于軟件開發中的極限編程(eXtreme Programming,XP),是其12個最佳實踐中的1個[1]。持續集成是為了保障產品質量,實現開發測試的快速迭代,盡早發現并解決問題。越來越多的人開始接受持續集成理念,自覺或不自覺地在項目中借鑒持續集成思想,使用持續集成工具,甚至開發自己的持續集成環境和工具。
1 最小持續集成環境
隨著軟件規模的不斷增大,測試用例數量隨之不斷增長,手工配置系統應用環境,手工進行軟件測試變得越來越低效。用自動化腳本維護測試用例、執行測試、返回測試結果的自動化測試成為趨勢。最小持續集成環境只需要一個任務定時啟動器和一個執行自動化測試的腳本,是實現持續集成的最簡單方式。如圖1所示,自動化測試腳本用于實現項目的具體測試需求,在Linux環境下可以用Crontab命令作為任務定時啟動器,在Windows環境下可以用計劃任務Bat命令作為任務定時啟動器。這樣,用一個自動化腳本和一個周期性配置命令就能搭建出最簡單的持續集成環境,但這種最小持續集成環境所實現的功能也相對簡單。 Crontab和Bat都是特定格式的命令文本,定時任務的查看和維護需要相應的背景知識,對于普通測試人員而言不夠方便和直觀。
2 軟件開發中的測試需求和可持續集成需求
2.1 測試需求分析
版本同步——軟件項目一般是多人同時開發,不同模塊和功能完成的時間前后不一,在執行編譯命令前需要進行代碼同步。
版本構建——用于將已完成的代碼進行編譯,如C++和Java等編譯性語言可分別使用GCC和Javac等編譯命令產生可執行的二進制文件,而解釋類語言一般不需要編譯。對于產品版本分支較多的情況,可能有多個選項控制產生多個不同目標版本。
單元測試——主要用于函數級和類級的測試,可用Gtest和Junit等測試框架編寫用例。而代碼覆蓋率檢查和代碼靜態檢查也可以劃歸為單元測試范疇,可使用Gcov和Jcoco等工具檢查代碼覆蓋率,可使用Cpplint和Jtest等工具進行代碼靜態檢查。
集成測試——在單元測試的基礎上,對組裝后的模塊或子系統進行測試,一般用代碼和腳本模擬外部行為,對集成模塊進行測試。
系統測試——將已經確認的軟件、硬件、外設、網絡等元素結合在一起,對整個系統進行確認性測試,一般用真實設備對系統進行測試。
負載測試——用于測試系統在不同負載情況下的性能表現和持續正常運行能力,一般采用高性能服務器作為測試的觸發源。
驗收測試——用于測試產品的功能和性能是否與需求說明書一致,如α測試是公司內部人員模擬真實用戶的操作行為和習慣對產品進行測試,而β測試是真實用戶直接對產品進行測試。
如圖2所示,版本同步、版本構建和單元測試一般可以在單機環境中完成,而集成測試和系統測試則可能涉及多個模擬或真實的外部設備,負載測試根據具體實現不同,可以只在單機完成,也可能涉及多個外部設備。
版本同步是開發人員將本地代碼與遠端服務器代碼進行同步,更新到最新版本或某個指定版本,一般只在開發人員的工作主機中完成。版本構建和單元測試雖然可以只在單機中完成,但為了提高構建和測試效率,也可以將單機串行任務劃分為多個任務,分發到多個服務器上并行執行,在多個服務器執行完畢后,將執行結果返回給主控服務器,由主控服務器判斷整個任務是否成功。將單機串行任務變成多服務器的并行任務,可以大大提高構建和測試的執行效率,但也使單機測試變成了涉及多個外部設備的協同測試,增加了持續集成實現的復雜度。
不同的軟件測試需求,涉及的實際網絡環境也各不相同,對于可能涉及多個外部設備的集成測試、系統測試、負載測試,要想實現持續集成,還必須考慮產品的版本部署和多個外部設備的環境配置等準備工作。
2.2 可持續集成需求分析
隨著開發者對持續集成思想的不斷接納,持續集成實踐早已不再局限于極限編程領域。從軟件開發測試流程來看,版本同步、版本構建、單元測試、集成測試、系統測試、負載測試等階段都可以通過腳本實現自動化,都有持續集成需求。而驗收測試一般是產品研發人員與用戶共同參與的測試,測試過程有很多的人工操作和干預,較少對其納入持續集成范疇。如圖3所示,是從測試需求角度分析軟件開發過程中的可持續集成部分。
版本同步是指用CVS、SVN、ClearCase、Git等版本控制工具將代碼更新到最新版本或指定版本,這個過程可以用腳本封裝起來,對于指定版本情況,可以設計腳本接受參數輸入。版本構建是指對剛剛同步過的版本進行編譯和鏈接。根據測試階段和目的不同,構建產生的可能不是最終的產品版本,如表1所示。
單元測試時,產生的是供單元測試用的版本,版本中除了包含產品代碼外,還包含對產品代碼進行測試的樁函數(Stub)代碼和測試用例。集成測試時,由于可能涉及輔助測試的模擬設備,構建產生的版本中可能包括與模擬設備相關的接口代碼。系統測試和驗收測試時,一般是將產品設備放在真實的系統應用場景中,由于不再涉及模擬設備接口代碼,因此應該產生正式版本。
負載測試比較特殊,不是驗證產品的功能,而是檢驗產品的最大用戶數、最快響應時間、最高處理能力等性能指標。如果實現方式基于產品本身系統,版本中包含的內容就與單元測試類似;如果實現方式基于模擬設備,版本中包含的內容就與集成測試類似;如果實現方式是真實設備直接測試,版本中包含的內容與系統測試和驗收測試一樣,只需要編譯正式版本即可。
當軟件項目規模較大時,如果編譯時間較長,可以用腳本實現多服務器并行編譯,此時還需考慮編譯的任務分發和結果回收等問題。
本文版本同步和版本構建劃分為兩部分,因為版本同步一般在開發者的單機環境中完成更新,而版本構建可交由多服務器并行實現以提高效率,是為了突出兩者持續集成的環境差別,實際項目中可以一起劃分到源代碼的版本管理和維護范疇。
多設備環境準備——對于有多個網絡設備的環境,一般是在版本構建完成后,將生成的版本部署到被測產品設備中。
由于存在多個網絡設備,可能涉及多個網絡設備的連接和配置問題。如果測試時使用了模擬其它網元的模擬設備,就要考慮模擬設備的連接和配置問題;如果模擬設備與被測產品有版本匹配問題,還要考慮模擬設備的版本同步、版本構建和版本部署等,相當于同時管理兩套代碼的部署問題。對于有多個網絡設備參與的測試,設備之間的連接和配置必不可少,而且是測試環境搭建中最不穩定、最易出錯和最應該實現持續集成的部分。如果每次都是人工手動配置,出錯的概率會很高,一般可以用腳本實現自動化配置,避免由于人工操作失誤而導致配置失敗。
測試執行——是持續集成的最核心部分,用測試用例驗證產品是否滿足設計需求。在具體執行測試前,要考慮測試用例列表準備、執行順序設置、失敗重試次數設置、日志目錄設置等自定義的選項。這種測試前的準備一般用腳本實現,用戶只要輸入參數即可完成設置。對于把測試用例從單機串行執行改為多服務器并行執行的情況,測試腳本還要考慮如何進行用例分發、結果回收、報告生成、日志歸集等功能。
日志歸集和結果報告——在測試執行完成后,要對生成的日志文件進行歸集以備后用,要對執行的結果進行分析以判斷成功或是失敗,還可以對比歷史結果生成執行成功趨勢圖,并用郵件的方式將測試結果、執行時間、日志路徑和鏈接地址等信息發送給相關開發測試人員。
版本部署——在所有的測試執行完成后,如果沒有出現測試用例失敗,就可以將經過測試的產品版本部署到實際應用環境中。
在多設備環境配置時,也涉及版本部署問題,但其是將各網絡設備的版本部署到實際測試環境中,包括單元測試的版本、集成測試的模擬工具版本、系統測試的被測產品版本。而在被測產品版本成功通過所有測試后的版本部署,是將經過驗證的真實軟件產品版本部署到實際的應用環境中。
3 持續集成工具選擇
明確了軟件的測試需求和可持續集成需求后,就要考慮采用什么樣的測試工具。在項目初始階段,為了實現快速的持續集成環境搭建,可以用本文開頭所述的“最小持續集成環境”方案。但隨著項目規模不斷增大,項目數量不斷增多,“最小持續集成環境”的任務啟動和進度監控等顯得不夠直觀。而且多個用戶通過配置crontab或bat文件管理持續集成任務也容易造成配置沖突,缺少全局性的任務規劃和管理。如果多個用戶在同一個時間段配置了某些很耗系統資源的任務,就會造成在某段時間內系統資源占用率高、任務執行耗時長、甚至日志文件讀寫沖突等問題。
針對以上可能存在的問題,可以考慮選擇CruiseControl[2-3]、Apache Continuum[4]、Jenkins/Hudson[5](Jenkins源于Hudson早期版本分支)等第三方持續集成工具。以近年來廣泛應用的開源項目Jenkins為例,其具有可定制化的項目Web配置界面,在項目建立時可以配置源碼管理、構建觸發器、構建環境、構建、構建后操作和通用設置6方面內容,涵蓋了項目測試時進行持續集成部署的各個方面。配置時可以直接在瀏覽器中輸入要執行的腳本或路徑;在腳本啟動后,可以通過Web頁面實時查看執行進度;在腳本執行完成后,圖形化標記結果成功或失敗,并可將執行結果發送到配置的郵件地址。
Jenkins官方網站中對其基本定位是一個可以支持多種自動化模式的自動機,支持任務串聯和并聯,并形象地這種串并聯后任務執行模式稱為管道(Pipeline)[6]。如圖4所示,是將圖2的軟件測試需求與圖3的軟件開發過程中的可持續集成部分結合,將實現不同功能的眾多小任務像管道一樣連接起來構成一個持續集成的大任務。Jenkins管道模式支持多任務并行,在完成必要的準備任務后,完成特定功能的眾多小任務可實現并行啟動,合理規劃和設計小任務的串并聯,可以大大提高任務的執行效率。
持續集成的目標是實現軟件開發的持續迭代,持續集成工具為這一目標提供了更加簡單和高效的實現方式,加上針對具體項目的自動化測試腳本,就使得原本必須手動執行的構建、測試、部署等工作變得不再困難。
4 基于Jenkins的無線4G LTE網絡持續集成實踐
4.1 多設備環境配置
不同于單機軟件,有多個網絡設備時涉及多個網元,配置更復雜,更容易出錯。如圖5所示的無線4G LTE網絡拓撲結構,包括基站(eNodeB)、用戶設備(UE)和核心網(EPC)等多個網絡設備。其中,深色eNodeB是真實被測設備,淺色eNodeB是輔助測試設備,可能是真實的,也可能是模擬的。多設備之間的通信接口,根據4G LTE網絡標準協議規定,eNodeB和UE之間的是uu接口,eNodeB和EPC之間的是s1接口,eNodeB之間的是x2接口。對eNodeB的測試就是驗證eNodeB與UE和EPC之間的信令流程是否滿足協議規定,數據傳輸是否穩定可靠。而在測試之前,保證eNodeB與眾多網絡設備之間的連通性,配置設備運行參數和檢查產品版本匹配等問題,都是多設備環境配置必須考慮的。
以工作中實際的4G LTE項目為例,使用上述可持續集成需求分析方法進行多設備環境配置需求分析。如表2所示,系統測試和集成測試只有多設備環境,對系統測試而言,涉及兩個真實eNodeB的版本部署和參數配置、真實UE參數配置、真實EPC版本部署和參數配置;對集成測試而言,涉及一個真實eNodeB版本部署和參數配置、一個模擬eNodeB版本部署和參數配置、模擬UE參數配置、模擬EPC版本部署和參數配置。單元測試用樁函數(Stub)屏蔽底層接口消息,有單服務器環境和多服務器環境兩個版本,多服務器版本除了考慮單個服務器配置外,還要考慮多服務器并行測試時的任務分發和結果回收;負載測試也有單機環境和多設備環境兩個版本,負載測試的單機環境與單元測試的單機環境類似,也是由樁函數(Stub)屏蔽底層接口消息,只是測試用例更偏向大容量、高負載、多并發的應用場景;負載測試的多設備環境網絡組成與集成測試類似,除了一個真實的被測eNodeB之外,其它設備都是模擬的。4.2 Web統一訪問頁面實踐
在Jenkins服務器搭建完畢后,任務的建立、訪問和配置都是通過Web頁面完成,這使得任務的參數配置、腳本嵌入、進度監控、日志查看等都變得十分方便。Jenkins的任務顯示由橫向選項和縱向列表兩部分組成,如圖6所示,是無線4G LTE項目Jenkins服務器搭建完畢后的Web頁面。
隨著項目數量不斷增多,Web訪問界面的選項卡變得越來越擁擠,如果項目的名字過長,一個頁面只能放置有限的幾個項目。雖然可以在一個項目中建立多個子項目,并在子項目中再建立多個孫項目,建立起層級關系。但這樣建立起來的Jenkins項目層級太多,劃分的子孫項目太多,某些子孫項目可能只是為了實現啟動、停止、用戶認證或服務器連接等小任務而建立。更重要的是如果單個項目層級太多,日志文件就被分散在多個子孫項目中,當某個項目執行失敗時,為了查看這個失敗日志,就要一層層地進入子孫項目,訪問不夠方便,項目關系不夠明確。
基于上述考慮,可以嘗試對Jenkins的Web訪問接口進行二次封裝,不讓用戶直接訪問Jenkins的默認Web頁面,而是通過如圖7所示的定制界面進行任務的配置和提交。在點擊提交按鈕后,用戶會收到任務開始郵件,給出任務執行的鏈接地址,可以隨時監控任務進度;在任務執行完成后,用戶將收到結束通知郵件,給出日志文件的鏈接地址。如果任務失敗,還會給出失敗子任務或孫任務的鏈接地址,不必一層層地進入子孫項目查找;如果任務沒有失敗,用戶只需查看任務開始郵件和成功結束郵件,甚至無需知道Jenkins的存在。
這種對Jenkins Web頁面進行二次封裝的任務提交方式,讓用戶只關注項目本身,不必關注具體用什么持續集成工具實現,只有在查看日志時才會訪問到Jenkins的Web頁面。相比于使用Jenkins本身的Web服務,二次封裝方案對用戶屏蔽了持續集成工具,增加了Web服務器的開發成本,但實現了讓開發人員聚焦于開發和測試,而不是工具的目的。這種二次封裝方案,可以用于大項目合并,比如某些項目已經搭建了基于Jenkins的持續集成環境,而另外一些項目搭建了基于CruiseControl的持續集成環境。在項目合并時,可以統一Web訪問接口,屏蔽掉原來兩個項目的持續集成工具,只關注任務提交和執行結果,而將持續集成工具作為任務管理和日志查詢的工具。
5 結語
持續集成的目的是為了保證產品質量,在軟件開發過程中更好地支持快速迭代,高質量地完成開發和測試任務。持續集成工具的選擇要根據項目的實際需求和網絡環境,可以用最小持續集成環境,也可以自主開發持續集成工具,還可以使用Jenkins/Hudson、Apache Continuum、CruiseControl等持續集成工具。第三方持續集成工具普遍通過Web頁面進行任務訪問和配置,經過二次封裝的統一Web訪問頁面,可以讓用戶更加聚焦于開發和測試,而不是工具本身。在項目中選擇什么樣的持續集成環境和工具取決于項目的具體需要,還要考慮團隊成員的知識儲備和能力等問題。
參考文獻:
[1] KENT BECK.Extreme programming explained:embrace change[M].Addison-Wesley Professional:US ed Edition,1999.
[2] KEVIN A LEE.IBM Rational clearcase,ant,and cruisecontrol: the java developer's guide to accelerating and automating the build process[M].1 edition.IBM Press,2006.
[3] CruiseControl初探[EB/OL].http://cruisecontrol.sourceforge.net/index.html.
[4] Continuous integration and build server[EB/OL].http://continuum.apache.org/.
[5] Register for jenkins world 2017[EB/OL].https://jenkins.io/.
[6] Jenkins (software)[EB/OL].https://en.wikipedia.org/wiki/Jenkins_(software).
(責任編輯:孫 娟)