轉自http://blog.sina.com.cn/s/blog_ae2575ff01018b2o.html
從android sdk api 16開始,Android SDK開始支持兩個做功能UI測試的新工具。
uiautomatorviewer,一個用以掃描以及分析Android應用程序的UI部件的工具。
以及uiautomator ,一個提供API用以自定義UI測試的Java庫。
要應用上面兩個工具,除了需要android sdk api 16以上的前提條件外,還要求Android SDK Tools爲21版以上。
UiAutomator主要涉及一下幾個類,大多數位於源碼包的com.android.uiautomator.core下,其中粗體字部分爲主要會接觸到的類,熟知這5個類的作用,就可以大體順暢的寫出UiAutomator的測試用例。
UiAutomatorTestCase
UiDevice
UiSelector
UiScrollable
UiObject
UiCollection
UiTestAutomationBridge, UiAutomatorBridge
InteractionController, QueryController
UiWatcher
TestCase (Junit) -> UiAutomatorTestCase -> App Test
每個測試用例都需要繼承UiAutomatorTestCase,以實現測試環境的setup,teardown等同能。而UiAutomatorTestCase則是通過繼承Junit3中的TestCase類,並在其中的setUp() 、tearDown() 、getParams() 函數中。其中主要是用Bundle實現Android Activity之間的通訊。在UiAutomatorTestCase,還加入了getUiDevice()等關於UiDevice的 函數,以實現在測試的任意地方均可調用UiDevice()。
此類主要包含了獲取設備狀態信息,和模擬用戶至於設備的操作兩類api。
可以通過getDisplaySizeDp(), getDisplayWidth() , getDisplayHeight() ,getProductName() ,getCurrentActivityName(), getCurrentPackageName() 等獲取設備相關信息。
pressMenu(), pressBack(), pressHome(), pressSearch() ,pressDPadCenter(), pressDPadRight(), pressDPadLeft(), pressDPadUp(), pressDPadDown() ,pressDelete(), pressEnter(), pressKeyCode(), pressRecentApps(),click(),swipe(),getDisplayRotation() setOrientationLeft()… wakeUp(), sleep() ,dumpWindowHierarchy(), waitForWindowUpdate()等API可以靈活的操縱設備。
而takeScreenshot() 允許隨時對設備截屏。
主要是通過一定查詢方式,定位到所要操作的UI元素。
一般UI元素均可通過以下API定位:text(), textMatches(String regex), textStartsWith(), textContains() ,className() ,classNameMatches(String regex), className(Class type) ,Description(), descriptionMatches(String regex),descriptionStartsWith(),descriptionContains() ,packageName(), packageNameMatches(String regex)。
值得注意的是index()和 instance() 兩個函數,其中index()是當前頁面的ID編號,instance()則表示在一定都搜索結果下,獲取的子元素集的第幾個元素。如:
new UiSelector().className("android.widget.ImageView").enabled(true).instance(2);
另有enabled(), focused(), focusable(), scrollable(), selected(), checked(), clickable() ,longClickable() ,childSelector()等檢索條件,顧名思義。
UiObject可代表頁面的任意元素,它的各種屬性定位通常通過UiSelector來完成。
比較常用的Api如clickAndWaitForNewWindow(),表示點擊該元素,並且等待新新窗口的展示完畢。這一過程是Android UI Testing框架支持的,不需要額外的控制等待時間。
UiObject允許點擊該元素的具體一個部分,Api如clickTopLeft(), longClickBottomRight(),…
通過getText(), getContentDescription(), getVisibleBounds(),… 等api可獲取UiObject的相關屬性,getPackageName() 可用來明確是否打開了目標測試的App.
setText(), clearTextField() 可以 用來設置以及清空所關聯的輸入框。
waitForExists() 可以用來操縱相關等待或驗證。
UiCollection一般與UiSelector連用,如它的構造函數也要求提供Uiselector: UiCollection(UiSelector selector)。
它的api較少,主要用以從Uiselector篩選出的元素集中挑出所要的元素:getChildByDescription(), getChildByInstance(), getChildByText() ,以及統計元素集的個數getChildCount()
UiObject -> UiCollection ->UiScrollable
UiScrollable 用來表示可以滑動的界面元素,其繼承關係如上圖所示。
其Api中,setAsVerticalList(), setAsHorizontalList() 用以設置Ui元素列表是基於橫向滾動還是縱向滾動。其後可以用getMaxSearchSwipes() ,flingForward(), flingBackward() ,scrollForward(),scrollBackward() ,scrollToEnd(), scrollToBeginning()
等函數控制滑動,以及getChildByDescription(), getChildByInstance(), getChildByText() ,scrollIntoView(), scrollTextIntoView(),… 來選擇是否已經轉換到具有目標元素的頁面。如:
UiScrollable appViews = new UiScrollable(new UiSelector().scrollable(true));
appViews.setAsHorizontalList();
UiObject helperApp;
helperApp = appViews.getChildByText(new UiSelector()
.className(android.widget.TextView.class.getName()), " 91助手 "); 則若當前頁面沒有91助手APP, 測試會自動滑動頁面,直到91助手App出現。
下面介紹下UI Testing Framework構成的重要類:
這是整個Testing Framework的基礎,此類負責連接系統了,記錄最新的可鏈接事件(AccessibilityEvent) , 窗口內容查詢Api等。可以被Android App調用,或者Java程序從shell調用。
這裏需要注意兩個概念:
1、AccessibilityEvent:所有的Ui元素可以被操縱,因爲這些Event都是AccessibilityEvent。對於怎樣令頁面元素可以被操縱,使得相關的事件都是AccessibilityEvent,請參見Uiautomator 詞條-"確認程序可以被測試" 部分。
2、AccessibilityNodeInfo:視窗中的組件樹節點,也就是uiautomtorViewer中展示的各個節點。
Api中connect(), disconnect() 負責建立與設備的實際連接。
executeCommandAndWaitForAccessibilityEvent() performAccessibilityAction() findAccessibilityNodeInfosByText(), findAccessibilityNodeInfoByViewIdInActiveWindow() 都是其中重要的Api。
UiAutomatorBridge是UiTestAutomationBridge的子類,區別主要是在構造函數中加上了InteractionController 和QueryController 兩大對象的調用。以及一些常量定義等。除了上述差異,UiAutomatorBridge還定義了executeCommandAndWaitForAccessibilityEvent() 、onAccessibilityEvent() 、waitForIdle() 、addAccessibilityEventListener() 等函數。
介紹InteractionController,需要先提InteractionProvider,它負責注入用戶事件(如點擊、輸入等) ,並且反應事件的對應座標。
InteractionController則定義了幾乎所有至於手機的基礎操作,如runAndWaitForEvents(), clickAndWaitForEvents() ,click(), longTap(), scrollSwipe(),Swipe() ,clickAndWaitForNewWindow() ,touchUp(), touchDown(), TouchMove() ,isNaturalRotation(), setRotationRight(), setRotationLeft() ,freezeRotation()
,wakeDevice(), sleepDevice() 等。
QueryController負責把UiSelector 的查找信息轉化爲AccessibilityNodeInfo。
具體Api如下:findNodePatternRecursive(), translatePatternSelector(), translateReqularSelector(), translateCompoundSelector(), getRootNode() ,findAccessibilityNodeInfo()。
UiWatcher只在UiSelector無法找到匹配的結果時被調用,意在重試、等待頁面更新 (如彈出對話框)等。其中只有一個主要函數:checkForCondition() 。
它的相關函數均在UiDevice中,如:UiDevice.registerWatcher() ,UiDevice. resetWatcherTriggers() ,UiDevice.runWatchers() ,UiDevice.removeWatcher()