1. 程式人生 > >android開發之Jenkins並行完成UI的自動化測試

android開發之Jenkins並行完成UI的自動化測試

這裡寫圖片描述

現在的 IT 公司會為了進入不同的市場開發相應的 App,來自同一家公司的 App 總會具有相似的 UI 邏輯,但 UI 的細節、風格又各有區分。隨著產品的發展,抑或是在產品應用於新市場的過程中產生了舊 UI 邏輯的變種,用於測試所有 UI 邏輯的時間會與新 UI 的數量呈正比例關係增長。即使有 UI 的自動化框架可以用來減少測試所需的時間(例如 Calabash Android),使得每天只需要2個小時就能完成對 UI 的測試,但在這套 UI 衍生出四套“變種 UI”後,卻要花費8個小時才能完成測試。

這篇博文將利用 Continuous Integration (CI) 服務,同時在不同的裝置中執行 UI 測試,並介紹一種從根源上減少這種實際場景下自動化測試所需時間的方法。此外,我們的測試都是在真機上執行,而不是虛擬機器。

更貼近現實的自動化測試:有很多東西只能通過真機來反映,像記憶體消耗,CPU 消耗:虛擬機器通常都是消耗電腦的資源,而真機基本不會消耗電腦資源。

而且用真機進行測試價效比較高!Android 裝置都很便宜,所以你可以在需要裝置進行測試的時候毫不猶豫地買買買,如果用虛擬機器測試的話,由於虛擬機器會消耗很多電腦資源而且拓展電腦硬體很燒錢,這無疑會限制測試裝置的數量。

雖說博文裡同時使用了 Calabash Android 自動化框架 和 Jenkins CI,但我提到的大部分方法可以通過執行在任意 CI 服務上的 Android Debug Bridge (ADB) 應用於其他的自動化測試框架裡。

建立 Jenkins slaves 和 slave group

完成分散式構建的第一步就是建立 Jenkins slave,授權它管理多個“奴隸”。我們可以通過 Jenkins -> Manage Jenkins -> Manage Nodes 導航到 Jenkins slaves/nodes 的配置介面。

根據定義,Jenkins slave 用於完成 Jenkins 主機分發下來的任務。在我們的使用場景中,需要完成的任務則是執行在 Android 裝置上的自動化測試。為了完成這項任務,所有奴隸都可以執行在相同的機器上,也就是通過 USB 連線在電腦上的,具有執行 ADB 命令的 Android 裝置。

下面是一個與 Samsung S3 關聯的奴隸的安裝細節:

這裡寫圖片描述

當所有奴隸都執行在同一臺機器上時,我建議為不同的奴隸結點提供不同的系統 roots 檔案,因為它們很可能會在測試結果處被儲存,如果它們指向同一個 root 檔案,可能會讓測試結果被不同的結點重寫。我們可以通過 Remote FS root 進行這樣的設定。

Remote FS root

每個奴隸都需要擁有 Jenkins 中的一個專用目錄,我們在奴隸中為其指定絕對路徑,如:’/var/jenkins’ 或 ‘c:\jenkins’,而且該路徑應該是奴隸裝置中的本地路徑。但是該路徑不需要對 Jenkins 可見,怎麼正常怎麼來就行。

奴隸不會持有重要資料(不同於最後創建於其上的專案的活躍工作區),所以你可以將奴隸的工作區設定到一個臨時目錄。這樣做的唯一缺點在於:你可能會在奴隸裝置關機後失去最新的工作區。

當 separate FS roots 和多處理器允許 Calabash 的並行操作時,ADB_DEVICE_ARG 環境變數需要用於通知 Calabash,因為 Calabash 執行的裝置應該向其傳送 ADB 命令,防止裝置的多重連線。底層中,Calabash 通過 ADB 裝置命令自動化 UI,當一個裝置匹配於另一個奴隸結點,ADB_DEVICE_ARG 應該通過環境變數的配置應用到 node 結點層中,並在其後在任務層變為可用。

環境變數

這些鍵值對將會應用於結點上的每一個構建,並重寫任意全域性值,所以他們能在 Jenkins 的配置中被使用(如 key{key}),而且將會被新增到構建上啟動的程序。

在 Nexus 4 中設定奴隸的方式上:

這裡寫圖片描述

如果你留心注意一些細節你會發現,所有奴隸結點都被配置了相同的 android-group 標籤。這樣做的目的主要是將奴隸分組,使得當我們需要使用奴隸時,方便我們呼叫特定分組裡的所有奴隸。

標籤

標籤(AKA 標籤)用於將多個奴隸分到一個邏輯組中,而每一個標籤都會消耗空間。例如 ‘regression java6′ 將為為結點分配 ‘regression’ 和 ‘java6′ 標籤。

舉例來說吧,如果你有多個視窗奴隸,而且你要完成的任務需要視窗,那麼你可以讓你的所有視窗奴隸持有 ‘windows’ 標籤,然後將需要執行的任務與 ‘windows’ 標籤繫結。這使得你的任務在所有視窗奴隸中被執行,而不是被隨意執行。

這裡寫圖片描述

現在如果我們檢查 android-group,我們會得到一個所有結點都帶著 android-group 標籤的列表,把其他裝置新增到這個組裡就像拷貝一個已存在的結點和更新 ADB_DEVICE_ARG 環境變數一樣簡單。

使用奴隸群建立並行任務

在進行了上面的配置以後,我們現在可以建立一個 Jenkins 任務使用連線到電腦的裝置,通過各自的奴隸和具有 android-group 的奴隸群執行 Calabash Android。

這裡寫圖片描述

通過選中“如果必要的話,執行並行構建”和“限制專案執行位置”兩個配置選項,使得任務可以被並行執行,主題對結點可用,僅使用標有“android-group”標籤的結點。但其中的限制是:需要確保只有與已連線的裝置關聯的結點才能用於自動化測試,因為我們有用於完成其他任務的其他與未連線裝置關聯的結點。

如果必要的話,執行並行構建

如果需要並行執行構建,Jenkins 會安排並並行執行多個構建(假設你有足夠的執行器和傳入的構建請求),這對於耗時長的構建和測試任務來說非常有用……此外,引數化構建也是非常實用的,因為每一個執行器的執行任務與其他執行器的執行任務相互獨立。

現在假設我們有4個自動化測試的請求和三個已連線的裝置,處理完所有請求將需要兩輪操作(第一輪三個裝置將會被使用,剩下一個請求在佇列中等待處理,當某個裝置變為空閒狀態則會處理該請求)。這就意味著我們可以使4個產品風格自動化測試的時間從8小時減少為4小時,如果我們再買一臺或者多臺裝置的話,時間甚至會更少。

通過上游任務觸發並行的下游任務

寫到這裡,我們已經能夠隨心所欲地對我們想要的裝置(連線在 USB 埠處可用的裝置!)手動地觸發並行的自動化測試。但是,我們為什麼要手動地完成這些工作呢?我們可以用 Jenkins Parameterized Trigger Plugin 設定上游任務,通過相應的引數觸發多個下游任務。

例如,如果我們想要使用所有可用裝置並行地測試多個應用 UI,那麼我們可以設定一個這樣的上游任務,並執行它:

這裡寫圖片描述
這裡寫圖片描述

上面的配置完成後,我們可以觸發三個並行的 MOBILE_TEST 下游任務(必須進行了“如果必要的話,執行並行構建”的配置),每一個下游任務將會測試一個指定的 App 風格“cherry”,“tomato”,“rasberry”,並通過一個叫作風格的引數傳送到下游任務。上游任務將會被阻塞,等待所有下游任務完成任務並因此設定構建狀態。

我建議大家把上游任務執行在不同的奴隸結點/奴隸組中,而不是執行在和下游任務相同的奴隸結點/奴隸組中,否則它將佔著裝置不處理,浪費了資源。

這裡寫圖片描述

所以從今天開始,讓我們一起回收這些被淘汰的裝置,讓它為我們貢獻最後一絲價值吧!