Android自動化框架uiautomator簡介


UI自動化測試框架,安卓移動端APP.
要求:Android 4.3以上
1.提供一系列API:執行UI測試在系統或者第三方APP上面;
2.允許在被測設備上執行操作,比如打開系統設置菜單。
3.適合編寫黑盒自動化測試
UIautomator框架主要特點:
1.元素定位:UIautomator viewer。掃描、分析待測應用的UI組件的圖像工具;
2.元素操作:Accessing devicestate.在目標設備和app上的各種操作
3.元素識別:UI Automator APIs,在多個應用程序中捕獲和操作UI組件。
 
1.uiautomatorviewer
uiautomatorviewer位於sdk/tools目錄下,可以掃描、分析待測試應用界面,分析結果可以導出為xml與截圖。通過該工具可以分析出UI控件的id,text,focusable等等各種屬性,甚至布局上的層次關系。
windows下運行tools下的uiautomatorviewer.bat
liunx下運行./uiautomatorviewer  啟動該工具。
上圖uiautomatorviewer的運行截圖,左上角兩個手機模樣的圖標點擊后就會開始截圖並分析UI組件,分析后的結果如下方所示, 左側為手機當前畫面截圖,右側上部為view控件的層次關系,下部為當前選中控件的各種信息。

2.uiautomator APIs

uiautomator是一個包含一套UI測試API,和支持運行測試程序的JAR包。該JAR包位於sdk/platforms/android-* /uiautomator.jar. 使用時需要注意自己的SDK版本需要大於16, SDK Tools版本需要大於21.Android版本需要高於4.3。
UIautomator有比較多的類。這里只介紹我們在APP自動化測試中常用的三種。其中UiSelector類是在appium定位元素時會用到的類。
UiSelector類

一、UiSelector作用

  按照一定的條件(例如控件的text值,資源id),定位界面上的元素。UiSelector對象的最終目的是去構造一個UiObject對象。

 

二、元素定位

 

1、根據text定位:

函數返回值 函數體 說明 用法
UiSelector text(String text) 根據“控件text屬性的內容”構造出UiSelector對象 例如,一個控件text的值是“發現”,UiSelector s = new UiSelector().text("發現");
UiSelector textContains(String text) 根據“控件text屬性包含的內容”構造出UiSelector對象 同上例子:UiSelector s = new UiSelector().textContains("現");
UiSelector textMatches(String regex)  根據“控件text屬性正則表達式的內容”構造出UiSelector對象 正則表達式語法參考網上資料即可。
UiSelector textStartsWith(String text) 根據“控件text屬性開始的內容”構造出UiSelector對象 同上例子:UiSelector s = new UiSelector().textStartsWith("發");

比較常用,准確度也比較高,中文查找的時候,有時候text元素是中文的,比如例如,一個控件text的值是“發現”,UiSelector s = new UiSelector().text("發現");此時運行的時候可能會報錯 “UiOjbectNotFoundException” ,這時候只要把項目的編碼格式改為utf-8就可以了。

 

2、根據description構造:

UiSelector description(String desc) 根據“控件content-desc屬性的內容”構造出UiSelector對象
UiSelector descriptionContains(String desc) 包含**
UiSelector descriptionMatches(String regex) 正則
UiSelector descriptionStartsWith(String desc) 以**開始

同text的用法基本一致,也是比較靠譜的一種方式。

 

3、根據資源id:

UiSelector resourceId(String id) 根據資源id獲取對象,例如:UiSelector s = new UiSelector().resourceId("com.tencent.mm:id/b8m")
UiSelector resourceIdMatches(String regex) 根據資源id的正則表達式獲取對象

 

4、根據類:

  1)UiSelector className(String  className):

  根據控件的類名來找到UiSelector對象。如圖

  

  這時候會出現問題:

  因為一般Android布局的時候,同樣的控件類名都是一樣的。

  因此我在微信的登錄界面調用: UiSelector s = new UiSelector().className("android.widget.TextView"),它得到的就是我左上開始算第一個class名稱為“android.widget.TextView”的控件。

  2)UiSelector instance (int instance):

  上面提到的假如我們想獲取屏幕上電話號碼的那個TextView使用這樣方法,就可以使用instance:

  UiSelector s = new UiSelector().className("android.widget.TextView").instance(1);

  3)UiSelector index(int index):

  用法和上面的instance差不多,谷歌的原文說這個方法是unreliable的,推薦使用instance方法。

  4)UiSelector childSelector(UiSelector selector):

  有的時候假如子控件不好獲得,而其父控件比較好獲得的時候,我們通常采用這樣的方式,例如下面:

  

  如圖,LinearLayout就是ImageView和EditText的父控件,當子空間text、resource-id為空的時候,這種時候子控件定位比較困難。很明顯,父控件id已經給定,那我們就可以先定位到父控件,再定位到子控件這種方法。

  在它的父控件的childSelector方法中傳入一個帶有一定特征的UiSelector對象,即可得到子控件  

  UiObject wx_input= new UiObject(new UiSelector().className("android.widget.RelativeLayout").childSelector(new UiSelector().className("android.widget.EditText")));   

  5)UiSelector fromParent(UiSelector selector):

  有的時候父控件也不好獲得,而是同級的控件(同屬一個parent)比較好獲取,那么使用這樣方法,還拿上面的舉例:

  我們先得到EditText的UiSelector對象:UiSelector s1 = new UiSelector().resourceId("com.tencent.mm:id/axc");

  得到和它同樣一個父控件的ImageView的UiSelector對象:UiSelector s2 = fromParent( new UiSelector().className("android.widget.ImageView") );

 

更多詳情見:https://developer.android.com/reference/android/support/test/uiautomator/UiSelector.html

 

 UiObject類:安卓組件對象,類似於webdriver中的webelement隊形,提供了元素的屬性獲取和元素的各種操作。對象有許多模擬實際操作手機的方法和屬性。比如文本的編輯、點擊、輸入、手勢操作等。

1、點擊與長按

(1)相關API

 

返回值 API 說明
boolean click() 點擊對象
boolean clickAndWaitForNewWindow(long timeout) 點擊對象,等待新窗口出現,參數為等待超時時長
boolean clickAndWaitForNewWindow() 點擊對象,等待新窗口出現
boolean clickBottomRight() 點擊對象的右下角
boolean clickTopLeft() 點擊對象的左上角
boolean longClick() 長按對象,對對象執行長按操作
boolean longClickBottomRight() 長按對象的右下角
boolean longClickTopLeft() 長按對象的左上角

 

 

(2)示例

new UiObject(new Selector().resourceId("xxxxx")).click();//對指定資源id的組件執行點擊操作

2、拖拽與滑動
(1)區別
拖拽:將控件從當前位置移動到指定位置
滑動:向某一方向(上、下、左、右)移動一小段距離

(2)相關API

返回值 API 說明
boolean dragTo(UiObject destObj, int steps) 拖拽對象到另一個對象位置上,步長可設置拖動的速度
boolean dragTo(int destX, int destY, int steps) 拖拽對象到屏幕某個坐標位置上,步長可設置拖動速度
boolean swipeDown(int steps) 拖動對象往下滑動
boolean swipeLeft(int steps) 拖動對象往左滑動
boolean swipeRight(int steps) 拖動對象往右滑動
boolean swipeUp(int steps) 拖動對象往上滑動

 

3、輸入文本與清除文本

(1)相關API

返回值 API 說明
boolean setText(String text) 在對象中輸入文本(實現方式:先清除文本再輸入)
void clearTextField() 清除編輯框中的文本(實現方式:長按再清除)

 

(2)補充說明

clearTextField()的內部實現方式是先長按文本框然后全選刪除,導致有些編輯框無法通過調用該方法清除文本內容。這時最好自己寫代碼實現清除文本功能。

示例代碼:

//將光標移動到行尾,使用backspace進行逐個刪除

UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_MOVE_END);

//判斷條件中w是編輯框為空時所顯示的hint文本對象;當hint出現時,說明該編輯框內的文本已清空

while(!w.exists()){
UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_DEL);
}

4、獲取對象的屬性與屬性的判斷

 

(1)獲取對象的屬性-相關API

返回值 API 說明
Rect getBounds() 獲得對象矩形坐標,矩形左上角坐標與右下角坐標
int getChildCount() 獲得下一級子類數量
String getClassName() 獲得對象類名屬性的類名文本
String getContentDescription() 獲得對象的描述屬性的描述文本
String getPackageName() 獲得對象包名屬性的包名文本
String getText() 獲得對象的文本屬性中的文本
Rect getVisibleBounds() 返回可見視圖的范圍,如果視圖的部分是可見的,只有可見部分報告的范圍


(2)獲取父類與子類節點-相關API

 

返回值 API 說明
UiObject getChild(UiSelector selector) 獲得對象的子類對象,可以遞歸獲取子孫當中某個對象
UiObject getFromParent(UiSelector selector) 從父類獲取子類,按照UiSeletor獲取兄弟類(遞歸)

 

 

(3)屬性的判斷-相關API

返回值 API 說明
boolean isCheckable() 檢查對象的checkable屬性是否為true
boolean isChecked() 檢查對象的checked屬性是否為true
boolean isClickable() 檢查對象的clickable屬性是否為true
boolean isEnabled() 檢查對象的enabled屬性是否為true
boolean isFocusable() 檢查對象的focusable屬性是否為true
boolean isFocused() 檢查對象的focused屬性是否為true
boolean isLongClickable() 檢查對象的longclickable屬性是否為true
boolean isScrollable() 檢查對象的scrollable屬性是否為true
boolean isSelected() 檢查對象的selected屬性是否為true

 

5、手勢的操作

 

(1)手勢相關操作
兩指平移 
多指平移 
兩指合攏 o---> <---o
兩指擴張 <---oo--->

(2)相關API

返回值 API 說明
boolean performMultiPointerGesture(PointerCoords[]... touches) 執行單手指觸控手勢,可定義任意手勢,與形狀

boolean

performTwoPointerGesture(Point startPoint1, Point startPoint2, 
Point endPoint1, Point endPoint2, int steps)

執行任意兩個手指觸控手勢,模擬兩個手指手勢
boolean pinchIn(int percent, int steps) 手勢操作,兩點向內收縮
boolean pinchOut(int percent, int steps) 手勢操作,兩點向外張開

 

6、判斷對象是否存在

(1)相關API

返回值 API 說明
boolean waitForExists(long timeout) 等待對象出現
boolean waitUntilGone(long timeout) 等待對象消失
boolean exists() 檢查對象是否存在

UiDevices類:提供了一些列方法和屬性來模擬在手機上的實際操作,獲取設備信息:屏幕分辨率、選裝狀態、亮屏、滅屏...操作:按鍵、坐標操作、滑動、拖拽、截圖

一、UiDevice類簡介

1、UiDevice代表設備狀態。如屏幕的大小、旋轉方向、按壓各種按鍵等。

2、UiDevice為單例模式,可有2種方式獲取其實例。

(1)UiDevice.getInstance();--->推薦
(2)getUiDevice.pressHome();---->在類A中封裝方法,方法被類B調用的時候會出現空指針異常

3、主要功能
(1)獲取設備信息:屏幕分辨率、選裝狀態、亮滅屏......
(2)操作:按鍵、坐標操作、滑動、拖拽、截圖......
(3)監聽器功能

二、按鍵與KEYCODE使用

 

1、點擊按鍵 相關API

UiDevice實例調用以下方法即可實現點擊按鍵操作。

 

 

返回值 方法名 描述
boolean pressBack() 模擬短按返回back鍵
boolean pressDPadCenter() 模擬按軌跡球中點按鍵
boolean pressDPadDown() 模擬軌跡球向下按鍵
boolean pressDPadLeft() 模擬軌跡球向左按鍵
boolean pressDPadRight() 模擬軌跡球向右按鍵
boolean pressDPadUp() 模擬軌跡球向上按鍵
boolean pressDelete() 模擬短按刪除delete按鍵
boolean pressEnter() 模擬短按回車鍵
boolean pressHome() 模擬短按HOME鍵
boolean pressKeyCode(int keyCode, int metaState) 模擬短按鍵盤代碼keycode
boolean pressKeyCode(int keyCode) 模擬短按鍵盤代碼keycode
boolean pressMenu() 模擬短按menu鍵
boolean pressRecentApps() 模擬短按最近使用程序
boolean pressSearch() 模擬短按搜索鍵

 


2、KEYCODE 鍵盤映射碼

(1)KeyEvent:按鍵事件,每個鍵盤映射碼都保存在keyEvent的常量中。

(2)META Key

<1>輔助功能鍵: ALT、SHIFT、CAPS_LOCK

<2>輔助功能鍵的狀態

 

  激活狀態 metaState
base META_key未被激活 0
caps SHIFT或CAPS_LOCK被激活時 1
fn ALT被激活 2
caps_fn ALT,SHIFT或CAPS_LOCK同時被激活時 3

 

<3>示例

UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_A);//點擊輸入小寫字母a
UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_A,1);//點擊輸入大寫字母A

三、獲取坐標與坐標點擊

 

 1、坐標相關知識

(1)手機屏幕坐標:從左上角(0,0)開始到右下角(X,Y)
(2)dp:設備獨立像素,例如,320像素顯示到640像素上要拉伸一倍
(3)Point:代表一個點(x,y)

2、坐標相關API

UiDevice實例調用以下方法即可實現獲取坐標和點擊操作。
返回值 方法名 描述
boolean click(int x, int y) 使用坐標點擊屏幕
int getDisplayHeight() 獲取屏幕高度
Point getDisplaySizeDp() 獲取顯示尺寸返回顯示大小(設備獨立像素);屏幕旋轉返回的顯示大小調整
int getDisplayWidth()

獲得屏幕寬度

 

3、Uiautomator Viewer

(1)功能:獲取屏幕快照,並通過快照獲取到控件的屬性。

(2)啟用方式

方式一、啟動路徑:adt/sdk/tools/UiautomatorViewer 

方式二、Eclipse/DDMS/Devices/UiautomatorViewer 

 

(3)屏幕快照參數之控件坐標

 通過UiautomatorViewer獲取屏幕快照,選中目標控件,通過Node Detail / bounds[左上角頂點坐標][右下角頂點坐標] 可獲取到控件的位置。



4、示例

(1)

UiDevice.getInstance().click(399,355);//點擊[399,355]坐標點

(2)
int h = UiDevice.getInstance().getDisplayHeight();
int w = UiDevice.getInstance().getDisplayWidth();
UiDevice.getInstance().click(w/2,h/2); //點擊屏幕的中心點

(3)

UiObject object = new UiObject(new UiSelector.resoutceId("com.andr....控件Id"));//根據ID獲取控件

Rect r = object.getBounds();//獲取控件對應的矩形區域相關屬性
r.left; //矩形左上角頂點X坐標
r.top; //矩形左上角頂點Y坐標
r.right; //矩形右下角頂點X坐標
r.bottom; //矩形右下角頂點Y坐標
r.centerX(); //矩形的中心點X坐標
r.centerY(); //矩形的中心點Y坐標

四、拖拽與滑動

1、相關概念
(1)拖拽:將一個組件從一個坐標移動到另一個坐標處。
(2)滑動:手指從一個坐標點移動到另一個坐標點。
(3)步長:從一點滑動到另一點使用的時間,步長越短說明移動越快。

2、拖拽與滑動相關API

 

返回值 方法名 描述
boolean drag(int startX, int startY, int endX, int endY, int steps) 拖動對象從一個坐標拖動到另一個坐標,step表示拖拽過程使用的時間(ms)
boolean swipe(Point[] segments, int segmentSteps) 在點陣列中滑動,5ms一步
boolean swipe(int startX, int startY, int endX, int endY, int steps) 通過坐標滑動屏幕

 


3、示例:按照一個矩形的路徑滑動
 Point p1 = new Point();
 Point p2 = new Point();
 Point p3 = new Point(); 
 Point p4 = new Point();
 p1.x =277;
 p1.y =318; 
 ...... //設置四個頂點的橫縱坐標
 Point[] pp = {p1,p2,p3,p4};
 UiDevice.getInstance().swipe(pp,50); //每50毫秒走一步(從一個點滑動到下一個點)

五、旋轉屏幕

1 、旋轉屏幕相關知識
(1)旋轉方向:4個方向,分別為 0度,90度,180度,270度
(2)重力感應器
(3)固定位置與物理旋轉
固定位置:屏幕的方向固定在0、90、180、270度;
物理旋轉:與重力感應器連接,關閉了物理旋轉就是關閉了重力感應器。

2、屏幕旋轉相關API

 

返回值 方法名 描述
void setOrientationLeft() 通過禁用傳感器,然后模擬設備向左轉,並且固定位置
void setOrientationNatural() 通過禁用傳感器,然后模擬設備轉到其自然默認的方向,並且固定位置
void setOrientationRight() 通過禁用傳感器,然后模擬設備向右轉,並且固定位置
void unfreezeRotation() 重新啟用傳感器和允許物理旋轉
boolean isNaturalOrientation() 檢測設置是否處於默認旋轉狀態
int getDisplayRotation() 返回當前的顯示旋轉,0度,90度,180度,270度值分別為:0(Surface.ROTATION_0)、1(Surface.ROTATION_90)、2(類推)、3(類推)
void freezeRotation() 禁用傳感器和凍結裝置物理旋轉在其當前旋轉狀態

 


六、滅屏與喚醒

滅屏與喚醒相關API

返回值 方法名 描述
void wakeUp() 模擬按電源鍵,如果屏幕是喚醒的沒有任何作用
void sleep() 模擬按電源鍵,如果屏幕已經是關閉的則沒有任何作用
boolean isScreenOn() 檢查屏幕是否亮屏

 

七、截圖與等待空閑

 

1 、截圖與等待空閑相關知識
(1)圖片縮放比例:如縮小1/2,即將100*100px的圖片長寬都縮小為原來的1/2,50*50px。
(2)圖片質量:一般是指圖片的大小,質量越高圖片越大。
(3)File 類:文件或者文件夾。
(4)圖片格式 :截圖的格式都是PNG。
(5)空閑狀態:窗口沒有更新或界面無動作。
(6)窗口更新事件。

2、截圖相關API

 

返回值 方法名 描述
boolean takeScreenshot(File storePath) 把當前窗口截圖並將其存儲為png默認1.0f的規模(原尺寸)和90%質量,參數為file類的文件路徑。
boolean takeScreenshot(File storePath, float scale, int quality) 把當前窗口截圖為png格式圖片,可以自定義縮放比例與圖片質量。

 

參數說明:
storePath:存儲路徑,必須為png格式。
scale:縮放比例,1.0為原圖。
quality:圖片壓縮質量,范圍為0-100。

3、等待空閑相關API

 

返回值 方法名 描述
void waitForIdle(long timeout) 自定義超時等待當前應用處於空閑狀態
void waitForIdle() 等待當前應用處於空閑狀態,默認等待10s;即10s后還不處於空閑狀態則報錯,程序在該句代碼處中斷;10s內程序處於空閑狀態,則該句代碼執行完畢。
boolean waitForWindowUpdate(String packageName, long timeout) 等待窗口內容更新事件的發生

 

 

八、獲取包名&開啟通知欄&快速設置&獲取布局文件

 

1、相關知識
包名:應用的唯一標識。
通知欄:從手機頂部下滑,出現的下拉界面即通知欄。
快速設置:即通知欄中的快速設置控件,快速設置界面可設置網絡、屏幕亮度、飛行模式等。

2、相關API
返回值 方法名 描述
void getCurrentPackageName() 獲取當前界面的包名,即目前處於手機前台的應用的包名
void dumpWindowHierarchy(String fileName) 獲取當前界面的布局文件,fileName給布局文件命名如“layout.xml”,保存在/data/local/tmp/目錄下
boolean openNotification() 打開通知欄
boolean openQuickSettings() 打開快速設置

 

 更多具體用法見官方文檔:https://developer.android.google.cn/training/testing/ui-automator#ui-automator-apis


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM