標籤:
轉自:http://bbs2.c114.net/home.php?mod=space&uid=1025779&do=blog&id=5322
幾種常見的Android自動化測試架構及其應用
隨著Android應用得越來越廣,越來越多的公司推出了自己行動裝置 App測試平台。例如,百度的MTC、東軟易測雲、Testin雲測試平台……。由於自己所在項目組就是做終端測試載入器的,故抽空瞭解了下幾種常見的基於UI層面的自動化測試載入器。趁晚上有空總結下,好記心不如爛筆頭呀!
一 常見Android自動化測試架構及其應用
目前,Android基於UI層面的自動化測試載入器,都可以理解為是基於Android控制項層面的,涉及Widgets和WebView兩大類。其主流的測試方法主要有以下幾種。一種是通過Android提供的各種服務,來擷取當前視窗的視圖資訊。然後,在當前視圖內尋找目標控制項,並根據該控制項屬性資訊計算出該控制項中心點的座標,進而構造出一個Android Input事件來實現對應用的自動化測試。其主要特點是:測試代碼和被測應用各自運行在各自的進程內,相互獨立。其代表有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許可權。另外,關於Hierachyview,CSDN上有一篇很好地介紹Hierachyview實現原理的文章,其串連地址如下:
http://www.cnblogs.com/vowei/archive/2012/08/08/2627614.html。現摘錄其部分內容,關於從裝置側ViewServer擷取控制項階層圖的過程,以便大家更好地理解該模式。
HierachyViewerDirector.java(即Controller)通過DeviceBridge.java來和Android裝置通訊,而DeviceBridge.java具體是通過AndroidDebugBridage.java和DeviceConnection.java來和裝置通訊。備忘:Hierachyview本身採用MVC模式。
AndroidDebugBridge.java : AndroidDebugBridge.java是ADB API,位於ddmlib項目中。它實現了命令列版adb一樣的功能,在HierarchyViewer中主要用到其串連裝置,forward連接埠,啟動ViewServer等操作。
DeviceConnection.java: 負責和ViewServer通訊,向ViewServer發送命令並接受其返回的資訊。從而擷取Activity列表、控制項階層圖、等。
第二種應用模式Uiautomator。UiAutomator是Google仿照微軟Uiautomation提供的一套自動化架構,基於Android AccessilibilityService提供(註:Android AccessilibilityService,是一個可訪問服務,是一個為增強使用者介面並協助殘疾使用者的應用程式,或者使用者可能無法完全與裝置的互動。例如,使用者在開車。那麼使用者就有可能需要添加額外的或者替代的使用者反饋方式)。其應用方式有以下幾種,一種是UiAutomatorView+monkey,另一種是直接調用UiAutomator API。其中,第一種方法同hierachyview+monkey差不多。其區別是:UiAutomatorView通過ADB向裝置側發送一個dump命令,而不是建立一個socket,下載一個包含當前介面控制項布局資訊的xml檔案。相比較hierachyview下載的內容而言,該檔案小很多。因此,從效率上講,這種方法比第一種應用模式快很多。第二種方法,則是直接調用UiAutomator架構對外提供的API,主要有UiDevice、UiSelector、UiObject等。其原理與第一種方式,即HierachyView+Monkey,差不多。其過程大致是:首先,UiAutomator測試架構通過Accessibilityservice,擷取當前視窗的控制項層次關係及屬性資訊,並尋找到目標控制項。若是點擊事件,則計算出該控制項的中心點座標。其次,UiAutomator通過測試架構,注入使用者事件(點擊、輸入類操作),從而實現類比人的操作。UiAutomator對外提供UiAutomatorTestCase、UiDevice、UiSelector、UiObject、UiCollection、UiScrollable等類,其作用如下:
l UiAutomatorTestCase :繼承自Junit TestCase (Junit),對外提供setup、teardown等,以便初始化用例、清除環境等。
l UiDevice:此類主要包含了擷取裝置狀態資訊,和類比使用者至於裝置的操作兩類API。UiSelector,主要是通過一定查詢方式,定位到所要操作的UI元素。
l UiObject:UiObject可代表頁面的任意元素,它的各種屬性定位通常通過UiSelector來完成。
l UiCollection:UiCollection一般與UiSelector連用,如它的建構函式也要求提供Uiselector: UiCollection(UiSelector selector)。它的API較少,主要用以從Uiselector篩選出的元素集中挑出所要的元素:getChildByDescription(), getChildByInstance(), getChildByText() ,以及統計元素集的個數getChildCount()。
l UiScrollable:UiScrollable 用來表示可以滑動的介面元素,其繼承關係為UiObject -> UiCollection ->UiScrollable。
但UiAutomator的實現方式與HierachyView+Monkey有很大不一樣。以控制項點擊操作為例,其實現流程大致如下:
定義一個點擊對象Object,該對象則通過UiSelector對象定位到具體的控制項。而UiSelector則通過UiAutomatorBridge(它可看做是UiSelector與AccesibilityService之間的連接器),將查詢內容(AccessibilityNodeInfo)和輸入事件(AccessibilityEvent)傳給AccessibilityService。實際業務過程比這複雜的多。這樣,就實現了對某個控制項的尋找或點擊操作。備忘:AccessibilityEvent,所有可操縱的UI元素都定義為一個AccessibilityEeventt;AccessibilityNodeInfo指視窗中的組件樹節點。
第三種則是accessibilityservice。先來介紹下Accessibilityserveice服務。前面已經講過,它是一個Android的一個服務。若是用Accessibilityservice進行自動化,我們需要繼承Accessibilityservice開發一個服務。這樣,我們就可以依據這個服務擷取當前介面的控制項屬性資訊。其擷取內容跟Uiautomator一樣,都是AccessibilityNodeInfo。控制項資訊擷取到後,若是要進行點擊等操作,則可通過Monkey或其他方式,如Input等,來類比點擊操作。
上述幾種Android測試方法中,UiAutomator比較正統,是Google正式推出的,也是應用範圍最廣的。另外幾種方法,則見得不多,其中Hierachyview+monkey的方式,公司內部Ares就採用了。這類測試載入器的一個好處就是可以跨應用。但不足之處也很多,速度慢、不支援WebView等(這種模式下,對WebView控制有限,無法注入Java Script)。
接下來說下第二種架構,即Instrumentation,它是Android對外提供的一系列的測試方法的核心。Instumentation可看成一系列控制函數的集合,作用於系統和應用之間,類似於Windows中的Hook。在該測試架構下,主程式和測試程式需要運行在同一個進程中,見(圖片來源CSDN,連結地址:http://blog.csdn.net/jayfei0308/article/details/7950052)。
需要說明的是,在Android系統中,測試程式也是應用程式,我們可以將其看成一個沒有UI的應用。
其實現過程大致如下:,InstrumentationTestRunner通過調用Instrumentation殺除應用程式的進程,再用Instrumentation重啟該應用。這時,測試應用和被測應用就運行在同一進程下。測試應用怎麼知道該測試哪個應用呢?嗯,這是通過在測試工程的mainfest檔案中添加<Instrumentation>元素來實現的。當測試應用和被測應用運行在同一個進程裡,它們之間就可以通過Instrumentation來進行訊息互動,從而達到測試效果。當Instrumentation與某個程式互動時,其大致採用如下步驟:(資料來源:
http://blog.csdn.net/fireworkburn/article/details/20144153)。
首先,啟動時,初始化測試APK的設定檔AndroidManifest.xml檔案中。該設定檔中標明了所使用的測試回合類、被測目標應用、包名等。然後,啟動被測應用的Activity。同時,將測試ActivityThread做為一個引用進行初始化。此時,如果找不到目標應用則會報錯。其次,執行測試指令碼。測試時,測試工程中任何對目標應用進行的操作,都會用非同步方式,將訊息體放在目標程式的MessageQueue中。這樣,目標程式在查看到自己的MessageQueue中有內容時就會執行。
基於Android Instrumentiaon開發的測試載入器有很多,其中最有名的恐怕要數Robotium了。目前,網路上很多行動裝置 App測試平台,如百度行動裝置 App測試平台MTC,都支援Robotium。
二 各類Android測試載入器的TestCase繼承關係
Android提供了很多測試載入器,如Monkey、Instrumentation、UiAutomator。其中,基於Android測試載入器進行二次開發的測試載入器也很多,如Robotium、Espresso。它們的繼承關係:
UiAutomator Testcase類繼承自JUnit的TestCase類。而Robotium、Espresso則繼承自activityInstrumentationTestCase2。從這個繼承關係,我們也能理解為什麼採用Robotium的方式,應用需要簽名。而採用UiAutomator則不需要。其原因是:採用Robotium的方式,其測試代碼本質上是一個APK。根據Android的安全機制,應用是需要簽名的。
三 常見Android自動化架構優缺點關係
這裡主要介紹下前面講的幾種測試載入器的優缺點,包括HierachyView+Monkey、UiAutomator、Robotium。
| |
Hierachyview+Monkey |
UiAutomator + Monkey |
Robotium |
許可權 |
root |
普通 |
普通 |
是否需要簽名 |
是 |
否 |
否 |
響應速度 |
10s(網友測試資料) |
4s(網友測試資料) |
1-2s |
是否支援WebView |
否 |
否 |
是 |
是否支援跨應用測試 |
是 |
是 |
否 |
支援該特性的Android API |
? |
API 16 |
API 7 |
是否支援控制項ID |
是 |
否 |
是 |
從上述資料來看,Android提供的測試載入器各有優缺點,有的支援WebView測試,有的不支援。有的支援跨應用,有的不支援。因此,一個好的Android測試載入器,更多地是相容了上述幾種測試方法。例如,Appium。
Android自動化架構 類比操作 類比測試