整合 Jenkins 和 TestNG 實現自助式自動化測試平臺
背景介紹
在軟體業十分成熟的今天,敏捷(Agile)開發在業界日益流行,而面臨的挑戰也日益增多,不斷變化的使用者需求、縮短的開發週期、頻繁的部署上線、複雜的產品架構和團隊組織,如何繼續保證軟體的質量是一個不能迴避的課題。
許多企業級規模的專案常常按照功能模組將龐大的團隊分為多個獨立的 Scrum 團隊。在這種情況下,每個 Scrum 團隊各自負責其所屬功能模組的開發和測試。在 Scrum 團隊中各種角色在不同的時間點有針對性不同的測試需求。其次,Build 部署以及測試頻率大幅增加。測試型別和階段也更加細化。
而現有的自動化測試,常常由獨立的自動化測試團隊來執行和維護。其他的 Scrum 團隊成員除非十分了解自動化測試包的細節,否則無法按照自身多型別的測試需求來執行自動化指令碼。並且有些專案自動化測試包涵蓋了成百上千的測試用例,僅僅因為需要驗證某個模組或某幾個功能點是否成功而執行整個測試包不僅費時且沒有必要。
本文針對以上涉及的問題,提出以下的解決方案:利用 Jenkins 和 TestNG 搭建“自助式”自動化測試平臺,充分利用了 Jenkins 成熟的平臺及其外掛, 以及 TestNG 對選擇測試用例的內在支援。
該平臺具有以下優點:
- 基於成熟的測試工具。Jenkins 是目前業內最流行的快速持續整合工具之一, 其穩定的效能和豐富的擴充套件性, 使得很多的團隊都優先選擇它作為專案的主要支援工具。TestNG 作為一款強大的 Java 測試框架,其在 Junit,NUnit 的基礎上做了廣泛的增強,從單元測試、功能測試到整合測試,都能提供良好的支援。這兩個工具一方面功能穩定,有大量的實際使用案例和文件支援,另一方面由於其屬於主流工具,很多團隊已經有過相應的經驗,可以大大縮短學習曲線和成本。
- 靈活地定製自動化測試。團隊成員通過登陸平臺 Web 介面,按照需求任意選擇部署在平臺上的自動化測試包,目標測試環境,測試集和測試用例。提交定製化的自動化執行請求,執行結束系統自動發郵件通知。不同人員的請求可以實現並行執行。
- 所有的自動化執行歷史記錄都可以儲存在平臺上。可以通過 Web 的方式隨時查閱。
- Jenkins 支援豐富的外掛,使用者可以按照需求進行選擇安裝和配置,以實現生成執行狀態表格,自動部署/更新自動化測試包等高階功能。
方案設計概述
本文將使用一個簡化後的“自助式”自動化測試應用場景以介紹本方案的核心設計思想。首先列舉出該平臺需要滿足的各項需求:
- 使用者許可權管理,使用者可以使用自己的帳號進行登陸訪問,提交請求。
- 使用者根據自身的具體需求,靈活的選擇已經部署在平臺上的自動化測試包,並且可以對測試環境,測試集和測試用例進行定製化選擇。
- 多使用者併發請求的執行,彼此之間相互獨立,互不干擾
- 請求執行完畢後的 email 通知
- 執行狀態和歷史紀錄的查詢
- 使用者體驗良好的 Web 頁面訪問模式
針對以上的需求,我們可以用圖 1 來簡要說明該方案的主要功能元件以及彼此之間的聯絡。
圖 1. 平臺主要功能元件
Web 前端:Jenkins 平臺自身提供一套統一標準的 web 介面,使用者可以根據需求通過其完成各種系統配置,任務提交,查詢等工作。
使用者登入與許可權控制:Jenkins 平臺預設支援若干種使用者驗證機制,比如 LDAP, Jenkins own database, servlet container authenticate 等等,也可以通過其它外掛實現更加複雜的驗證。本文將採用最簡單的 Jenkins own database 來管理帳戶的許可權。
任務請求定製化模組:一般來說,Jenkins 大部分情況下只需要完成預定義執行內容的任務。所以在引數定製化請求方面只具備最基本的支援。為了滿足更好的“自助式”的使用者體驗和需求,實現預定義任務對不同使用者需求的靈活響應,我們在還需要藉助一款 Jenkins 外掛“Extended Choice Parameter plugin”的輔助。利用該外掛,使用者可以在提交請求時在頁面上輸入多選式引數,這些動態輸入將以環境變數的形式傳遞給執行模組影響最終請求的行為。
任務提交與執行模組:Jenkins 支援穩定的任務管理機制,管理員可以通過配置使同一個任務支援併發響應多個請求,彼此之間獨立且互不干擾。
任務狀態與歷史紀錄查詢:對於任務請求的狀態資訊跟蹤,Jenkins 預設只支援控制檯輸出的監控,而且每一次請求記錄,Jenkins 只提供一個數字 ID 和時間戳進行標識。對於一個多使用者的自助式平臺這是遠遠不夠的。我們利用外掛“HTML Publisher Plugin”,儲存請求生成的 html 格式的執行報告。這樣可以在頁面上對任意歷史請求的執行紀錄和報告進行查詢和檢索;同時利用“EnvInject Plugin”,“Build User Vars Plugin”和“Build Name Setter Plugin”為每一次請求動態生成包含使用者姓名等多方面資訊的 ID 以區分,大大方便資訊的管理和測試結果資料的追溯。
Email 提醒:Jenkins 預設只支援最基本的 email 通知機制。我們使用外掛“Email-ext plugin”進行擴充套件,以支援更加強大的通知機制,靈活定製 email 標題和內容, 新增附件,定製收件人名單等。
TestNG 自動化測試框架:TestNG 是一款強大的自動化測試框架,適用於 Unit 測試,功能測試,整合測試等多型別的自動化測試。其擁有一整套成熟的 API 和 Annotation, 支援資料驅動,測試周期和依賴控制,多執行緒執行等一系列特性。本方案採用 TestNG 還因為其具有對測試指令碼集進行靈活選擇的特性。TestNG 利用 xml 檔案來組織測試指令碼集,在執行的時候,我們可以通過引數指定需要執行的指令碼,把 Jenkins 任務與建立在這一框架之上的自動化測試包進行連線,就可以輕鬆實現使用者在頁面上選擇測試集。
平臺的實現與配置
本章介紹該平臺具體的實現和配置流程,主要包含以下步驟:
- 安裝 Jenkins 及必要的第三方外掛
- 建立新使用者及配置許可權
-
為自動化測試建立和配置新任務
- 配置使用者輸入定製化選項
- 配置執行報告儲存
- 配置 email 提醒
Jenkins 及相關外掛的安裝 (本文以 jenkins-ver.1.524 為例)
Jenkins 是一款成熟強大的開源軟體,對大部分主流的作業系統平臺(Linux,Windows, Mac OS)都提供支援,在其官方網站上可以直接下載到最新的安裝包和每一個平臺的安裝流程文件。
安裝完畢之後,我們可以以後臺服務的形式將其啟動,這個時候我們就可以用瀏覽器通過 http://localhost:8080 訪問其預設主頁面進行平臺定製化配置。
圖 2.Jenkins 主頁面
初始安裝後的 Jenkins 並沒有預設管理員帳戶,第一次開啟主頁面就可以直接對其進行系統配置,在頁面的左端可以通過點選“Manage Jenkins”開啟 Jenkins 系統管理介面。
圖 3.Jenkins 管理介面
我們可以通過“Manage Plugins”來安裝第三方外掛。其中本方案建議安裝的六個外掛分別是“Extended Choice Parameter plugin”,“EnvInject Plugin”,“Build User Vars Plugin”,“Build Name Setter Plugin”,“HTML Publisher Plugin”和“Email-ext plugin”。
圖 4.Jenkins 外掛管理
安裝外掛的方法十分簡單,在“Manage Plugins”頁面的“Available”選項卡中,勾選所需要的目標外掛,點選頁面下方的相應安裝按鈕即可。
新建使用者和配置許可權
前面我們提到 Jenkins 在初次安裝時預設並沒有使用者驗證的環節,所有開啟主頁面的使用者都具有系統管理員許可權。對於一個要在正式專案中被整個團隊所公用的測試平臺,我們需要嚴格的建立使用者驗證和許可權配置。
首先在“Manage Jenkins ->Configure Global Security”頁面中勾選“Enable security”。頁面重新整理之後在“Security Realm”項選擇“Jenkins' own user database”,“Authorization”項選擇“Matrix-based security”,同時暫時賦給 Anonymous“Overall Admin”許可權. 每一個專案也可以根據自身的需要選擇其它的認證方式。
圖 5. 安全管理
儲存設定之後,回到 Jenkins 主頁面,此時我們點選右上角 sign up 連結可以進入建立使用者頁面,輸入新建使用者的基本資訊。通過這種方式可以為需要使用該平臺的所有成員建立屬於他們自己的專用賬號。
圖 6. 帳號建立
新建賬號完畢之後,用專門為管理員建立的賬號重新登陸,再次進入“Manage Jenkins ->Configure Global Security”,為我們剛才建立的團隊成員賬號設定許可權,同時禁用 Anonymous 的所有許可權,具體方式如圖 7 所示,儲存之後即可生效。
圖 7. 許可權配置
為自動化測試建立和配置新任務。當以上工作都準備完畢之後,就可以開始在 Jenkins 平臺上為自動化測試建立新的任務。首先在主介面的左上方點選“New Job”, 選擇“Build a free-style software project”型別,並且提供一個合適的任務名如“ProjectA RESTAPI automation”。
圖 8. 新 Job 建立
點選 OK 之後就可以開始對 Job 內容進行定義和配置。傳統的 Jenkins 平臺應用主要集中在持續整合(CI)領域,所以在配置頁面提供了大量的關於原始碼獲取,Build 建立等傳統配置選項。而本文從全新的角度利用 Jenkins 平臺的特性搭建自助式平臺,基於篇幅所限,這裡只介紹和本方案相關的主要配置項。
首先,為了讓自動化任務在提交請求的時候都能夠接收不同使用者的選擇,我們需要勾選“This build is parameterized”。在接下來的“Add Parameter”下拉選單中,Jenkins 提供多種型別的使用者輸入,在這裡我們選擇“Extended Choice Parameter”(這是由上文中提到的外掛“Extended Choice Parameter plugin”新增出的支援型別),同時 Jenkins 每一個 Job 支援多個使用者輸入選項,並且彼此之間可以屬於不同型別,管理員可以根據專案需要進行靈活搭配。
圖 9. 引數化配置
在這裡為了簡單起見,本文新建了兩個引數化輸入選項以說明問題。其中第一個為單選項,提供使用者對目標測試環境的選擇,另一個為多選項,提供對具體測試用例的選擇。每一個輸入項在配置時需要提供唯一標識的名字, 不僅會顯示在輸入頁面上,同時使用者提交請求時真實的輸入將會以同樣命名的環境變數的形式傳遞給具體的執行指令碼。其次對於備選項列表的配置,系統提供兩種方式。第一種是直接在“Value”項中提供所有備選項的列表,並以逗號隔開(如圖 10 中對環境選項 ENVIRONMENT 的配置),另一種是當備選列表比較長的時候我們可以以檔案的形式來提供(如圖 11 中對測試用例 SELECTED_TESTCASE 選項的配置)。備選列表檔案的內容格式如清單 1 所示:
清單 1. SELECTED_TESTCASE 選項的備選列表檔案內容
1 2 |
TestCase
= Testcase1,Testcase2,\
Testcase3
|
備選選項列表以檔案形式提供的好處之一是我們可以自己設計指令碼來自動生成和更新這個列表,這樣當自動化測試包有更新的時候我們並不需要每次都手動更新這些配置檔案。同時檔案的更新可以即時生效,這一點十分重要。
圖 10. 單選項配置
圖 11. 多選項配置
本例所示引數化配置之後,使用者在提交請求時,系統將會顯示如下頁面以提示使用者進行選擇,使用者可以根據需要自由的選擇測試的目標環境和測試用例集合。
圖 12. 引數化介面
其次,如果該 Job 需要支援多人提交請求的並行執行(前提是 Job 執行的內容本身不會因為並行執行產生問題,比如每個請求都需要獨佔某個僅有的目標資源等),我們可以勾選“Execute concurrent builds if necessary”,同時我們需要考慮 Jenkins 所在伺服器本身的配置和負荷能力。
圖 13. 並行配置
同時,每一個來自不同使用者的請求在系統中都會產生唯一的 ID 和時間戳以標示,但是這些資訊並不足以讓我們瞭解該請求的具體內容和發起人,可讀性是很差的。為了更方便閱讀和管理過往的記錄,在此可以為每一個請求動態生成包含多種可識別資訊的名字。我們利用“EnvInject Plugin”,“Build User Vars Plugin”和“Build Name Setter Plugin”三個外掛以實現為不同請求定製如圖 14 所示的名字。(Jenkins 自身提供部分系統環境變數如 BUILD_NUMBER, 之前為選擇目標測試環境而配置的使用者輸入提供了環境變數 ENVIRONMENT,“Build User Vars Plugin”外掛為我們提供了請求發起人的使用者名稱資訊 BUILD_USER)
圖 14. 請求命名 ID 的配置
通過以上的配置,不同使用者請求的歷史記錄將更加易於查詢和管理,如圖 15 所示
圖 15. 歷史記錄
緊接著就是通過配置“Build Step”來定義每次請求具體的執行內容,Jenkins 提供 Windows batch, shell, Ant, Maven 四種方式呼叫外部的命令和指令碼
圖 16.Build Step
我們將在 build step 的命令中呼叫基於 TestNG 框架的自動化測試包。TestNG 是利用一種特殊格式的 XML 檔案來定義測試用例集合的,稱之為測試套件檔案。假定我們專案的自動化測試包有一個包含三個 test 的測試套件 projectARestAPISuite.xml,如清單 2 所示,它所包含 test 的名字(test name 屬性)分別為 Testcase1,Testcase2,Testcase3。
清單 2. TestNG 測試套件檔案 projectARestAPISuite.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
< suite
name = "Project
A RestAPI automation suite" >
< test
name = "Testcase1" >
< classes >
< class
name = "tests.Testcase1"
/>
</ classes >
</ test >
< test
name = "Testcase2" >
< classes >
< class
name = "tests.Testcase2"
/>
</ classes >
</ test >
< test
name = "Testcase3" >
< classes >
< class
name = "tests.Testcase3"
/>
</
|