1. 程式人生 > >andorid 自動化測試初探

andorid 自動化測試初探

常見Android自動化測試框架及其應用

1. 目前,Android基於UI層面的自動化測試工具,都可以理解為是基於Android控制元件層面的,涉及WidgetsWebView兩大類。其主流的測試方法主要有以下幾種。一種是通過Android提供的各種服務,來獲取當前視窗的檢視資訊。然後,在當前檢視內查詢目標控制元件,並根據該控制元件屬性資訊計算出該控制元件中心點的座標,進而構造出一個AndroidInput事件來實現對應用的自動化測試。其主要特點是:測試程式碼和被測應用各自執行在各自的程序內,相互獨立。其代表有Uiautomator。另一種則是基於Instrumentation,通過把測試程式碼和應用程式碼,確切地說是測試

APK和被測APK,執行在同一個程序中,通過Java反射機制,來獲取當前視窗所有檢視,並根據該檢視查詢到目標控制元件的屬性資訊,並計算出目標控制元件中心點座標。然後,利用Instrument內部介面,實現點選操作。其代表有Robotium

第一種:這類方法通常需要滿足兩個功能,一是能獲取螢幕檢視;二是能產生輸入事件。這樣,使用者就可以通過螢幕檢視查詢到目標控制元件,進而計算出其中心點座標,並由此產生一個輸入事件來模擬使用者操作。通常,這類框架還會提供一個截圖功能,方便使用者對照。例如,分析定位問題等等。

目前,這類測試方法常見應用模式有以下幾種:(1)、Hierachyview+monkey

;(2)、uiautomator;(3)、accessibilityservice。(4)其他。先來說下第一種,Hierachyview+monkey的組合方式。

我們先來說下第一種,Hierachyview+monkey。其實現原理如下:

 首先,hierahcyview通過socket與裝置側ViewServer建立連線,埠為4939。其次,通過命令“dump -1”獲取控制元件屬性資訊。資訊存入ViewNode中。第三,根據ViewNode資訊,遍歷控制元件樹,查詢到目標控制元件,並根據其bounds資訊,計算出其中心點座標。第四,根據計算出的座標資訊,傳送一個點選該點的monkey

命令給裝置側的monkey服務。除點選操作外,我們還可以通過Monkey服務進行輸入、硬按鍵類操作。至此,對裝置的一個自動化操作就完成了。這裡需要說明的是,絕大部分商用手機ViewServer服務的開啟都需要系統許可權。故採用這種模式,手機一般需要root許可權。另外,關於HierachyviewCSDN上有一篇很好地介紹Hierachyview實現原理的文章,其連線地址如下:

 HierachyViewerDirector.java(即Controller)通過DeviceBridge.java來和Android裝置通訊,而DeviceBridge.java具體是通過AndroidDebugBridage.javaDeviceConnection.java來和裝置通訊。備註:Hierachyview本身採用MVC模式。

AndroidDebugBridge.java :AndroidDebugBridge.javaADB API,位於ddmlib專案中。它實現了命令列版adb一樣的功能,在HierarchyViewer中主要用到其連線裝置,forward埠,啟動ViewServer等操作。

DeviceConnection.java: 負責和ViewServer通訊,向ViewServer傳送命令並接受其返回的資訊。從而獲取Activity列表、控制元件層次結構圖、截圖等。

第二種應用模式UiautomatorUiAutomatorGoogle仿照微軟Uiautomation提供的一套自動化框架,基於AndroidAccessilibilityService提供(注:AndroidAccessilibilityService,是一個可訪問服務,是一個為增強使用者介面並幫助殘疾使用者的應用程式,或者使用者可能無法完全與裝置的互動。例如,使用者在開車。那麼使用者就有可能需要新增額外的或者替代的使用者反饋方式)。其應用方式有以下幾種,一種是UiAutomatorView+monkey,另一種是直接呼叫UiAutomatorAPI。其中,第一種方法同hierachyview+monkey差不多。其區別是:UiAutomatorView通過ADB向裝置側傳送一個dump命令,而不是建立一個socket,下載一個包含當前介面控制元件佈局資訊的xml檔案。相比較hierachyview下載的內容而言,該檔案小很多。因此,從效率上講,這種方法比第一種應用模式快很多。第二種方法,則是直接呼叫UiAutomator框架對外提供的API,主要有UiDeviceUiSelectorUiObject等。其原理與第一種方式,即HierachyView+Monkey,差不多。其過程大致是:首先,UiAutomator測試框架通過Accessibilityservice,獲取當前視窗的控制元件層次關係及屬性資訊,並查詢到目標控制元件。若是點選事件,則計算出該控制元件的中心點座標。其次,UiAutomator通過測試框架,注入使用者事件(點選、輸入類操作),從而實現模擬人的操作。UiAutomator對外提供UiAutomatorTestCaseUiDeviceUiSelectorUiObjectUiCollectionUiScrollable等類,其作用如下:

lUiAutomatorTestCase :繼承自JunitTestCase Junit),對外提供setupteardown等,以便初始化用例、清除環境等。

lUiDevice:此類主要包含了獲取裝置狀態資訊,和模擬使用者至於裝置的操作兩類APIUiSelector,主要是通過一定查詢方式,定位到所要操作的UI元素。

lUiObjectUiObject可代表頁面的任意元素,它的各種屬性定位通常通過UiSelector來完成。

lUiCollectionUiCollection一般與UiSelector連用,如它的建構函式也要求提供Uiselector:UiCollection(UiSelector selector)。它的API較少,主要用以從Uiselector篩選出的元素集中挑出所要的元素:getChildByDescription(),getChildByInstance(), getChildByText() ,以及統計元素集的個數getChildCount()

lUiScrollableUiScrollable 用來表示可以滑動的介面元素,其繼承關係為UiObject-> UiCollection ->UiScrollable

UiAutomator的實現方式與HierachyView+Monkey有很大不一樣。以控制元件點選操作為例,其實現流程大致如下:

定義一個點選物件Object,該物件則通過UiSelector物件定位到具體的控制元件。而UiSelector則通過UiAutomatorBridge(它可看做是UiSelectorAccesibilityService之間的聯結器),將查詢內容(AccessibilityNodeInfo)和輸入事件(AccessibilityEvent)傳給AccessibilityService。實際業務過程比這複雜的多。這樣,就實現了對某個控制元件的查詢或點選操作。備註:AccessibilityEvent,所有可操縱的UI元素都定義為一個AccessibilityEeventtAccessibilityNodeInfo指視窗中的元件樹節點。

第三種則是accessibilityservice。先來介紹下Accessibilityserveice服務。前面已經講過,它是一個Android的一個服務。若是用Accessibilityservice進行自動化,我們需要繼承Accessibilityservice開發一個服務。這樣,我們就可以依據這個服務獲取當前介面的控制元件屬性資訊。其獲取內容跟Uiautomator一樣,都是AccessibilityNodeInfo。控制元件資訊獲取到後,若是要進行點選等操作,則可通過Monkey或其他方式,如Input等,來模擬點選操作。

上述幾種Android測試方法中,UiAutomator比較正統,是Google正式推出的,也是應用範圍最廣的。另外幾種方法,則見得不多,其中Hierachyview+monkey的方式,公司內部Ares就採用了。這類測試工具的一個好處就是可以跨應用。但不足之處也很多,速度慢、不支援WebView等(這種模式下,對WebView控制有限,無法注入JavaScript)。

接下來說下第二種框架,即Instrumentation,它是Android對外提供的一系列的測試方法的核心。Instumentation可看成一系列控制函式的集合,作用於系統和應用之間,類似於Windows中的Hook。在該測試框架下,主程式和測試程式需要執行在同一個程序中,見下圖(圖片來源CSDN,連結地址:)。

需要說明的是,Android系統中,測試程式也是應用程式,我們可以將其看成一個沒有UI的應用。

其實現過程大致如下:如圖,InstrumentationTestRunner通過呼叫Instrumentation殺除應用程式的程序,再用Instrumentation重啟該應用。這時,測試應用和被測應用就執行在同一程序下。測試應用怎麼知道該測試哪個應用呢?嗯,這是通過在測試工程的mainfest檔案中新增元素來實現的。當測試應用和被測應用執行在同一個程序裡,它們之間就可以通過Instrumentation來進行訊息互動,從而達到測試效果。當Instrumentation與某個程式互動時,其大致採用如下步驟:(資料來源:

http://blog.csdn.net/fireworkburn/article/details/20144153)。

首先,啟動時,初始化測試APK的配置檔案AndroidManifest.xml檔案中。該配置檔案中標明瞭所使用的測試執行類、被測目標應用、包名等。然後,啟動被測應用的Activity。同時,將測試ActivityThread做為一個引用進行初始化。此時,如果找不到目標應用則會報錯。其次,執行測試指令碼。測試時,測試工程中任何對目標應用進行的操作,都會用非同步的方式,將訊息體放在目標程式的MessageQueue中。這樣,目標程式在檢視到自己的MessageQueue中有內容時就會執行。

基於AndroidInstrumentiaon開發的測試工具有很多,其中最有名的恐怕要數Robotium了。目前,網路上很多移動應用測試平臺,如百度移動應用測試平臺MTC,都支援Robotium

各類Android測試工具的TestCase繼承關係

Android提供了很多測試工具,如MonkeyInstrumentationUiAutomator。其中,基於Android測試工具進行二次開發的測試工具也很多,如RobotiumEspresso。它們的繼承關係下圖:

UiAutomatorTestcase類繼承自JUnitTestCase類。而RobotiumEspresso則繼承自activityInstrumentationTestCase2。從這個繼承關係,我們也能理解為什麼採用Robotium的方式,應用需要簽名。而採用UiAutomator則不需要。其原因是:採用Robotium的方式,其測試程式碼本質上是一個APK。根據Android的安全機制,應用是需要簽名的。

常見Android自動化框架優缺點關係

這裡主要介紹下前面講的幾種測試工具的優缺點,包括HierachyView+MonkeyUiAutomatorRobotium

Hierachyview+Monkey

UiAutomator + Monkey

Robotium

許可權

root

普通

普通

是否需要簽名

響應速度

10s(網友測試資料)

4s(網友測試資料)

1-2s

是否支援WebView

是否支援跨應用測試

支援該特性的Android API

?

API 16

API 7

是否支援控制元件ID

從上述資料來看,Android提供的測試工具各有優缺點,有的支援WebView測試,有的不支援。有的支援跨應用,有的不支援。因此,一個好的Android測試工具,更多地是相容了上述幾種測試方法。例如,Appium