【Android測試】Uiautomator——API詳解
簡單的例子
以一個簡單的例子開始吧。我們完成一個 " 開啟QQ,進入QQ空間,然後退出 " 的case。
程式碼如下:
- package QQ;
- import java.io.IOException;
- import com.android.uiautomator.core.UiDevice;
- import com.android.uiautomator.core.UiObject;
- import com.android.uiautomator.core.UiObjectNotFoundException;
-
import
- import com.android.uiautomator.testrunner.UiAutomatorTestCase;
- publicclass Test_qq extends UiAutomatorTestCase
- {
- publicvoid testDemo() throws IOException, UiObjectNotFoundException {
- // 啟應用
-
Runtime.getRuntime().exec("am start com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
- sleep(3000);
- // 點選 "動態" tab
- UiDevice device = getUiDevice();
- int height = device.getDisplayHeight();
- int width = device.getDisplayWidth();
- device.click(width -50, height-50);
- sleep(1000);
- // 點選 "好友動態" 按鈕
-
UiObject obj_1 = new
- obj_1.click();
- sleep(2000);
- // 點選 左上角返回 "動態"按鈕
- UiObject obj_2 = new UiObject(new UiSelector().resourceId("com.tencent.mobileqq:id/ivTitleBtnLeft"));
- obj_2.click();
- sleep(1000);
- // 點選選單鍵
- device.pressMenu();
- sleep(1000);
- // 點選退出qq
- UiObject obj_3 = new UiObject(new UiSelector().text("退出QQ"));
- obj_3.click();
- sleep(1000);
- // 點選確定
- UiObject obj_4 = new UiObject(new UiSelector().text("確定"));
- obj_4.click();
- }
- }
指令碼的執行效果如下:
程式碼詳解
針對上面的例子的程式碼,我對每一句程式碼都做個詳細的解釋吧。
第一部分:啟動應用
exec() 這個函式的意思,相當於是在你在輸入adb shell 命令後,在Android手機系統的命令列下執行。所以上面這句話的意思和我們開啟cmd框輸入" adb shell am start *** " 是一樣的的效果。
一般來說我們做App的自動化的時候,第一步都是把App開啟,這個am start命令的就可以幫我們實現,類似與Monkeyrunner API中的startActivity() 函式。
第二部分:點選 “動態” tab
UiDevice物件會在API部分詳細講解,它是一個我們在Uiautomator中經常使用的一個物件。
這裡我們首先用它獲取到當前手機的寬和高的畫素。然後觀察到 “動態” tab位於右下方,因此在取得右下角的座標點後,又進行了一個大概的座標變化(這裡為了簡單只是向左和向上移動了50畫素,如果要精確的可以進行等比轉化),然後點選該座標。
這裡之所以用點選座標的方法,一方面是因為這個控制元件Uiautomator不支援用API獲得例項(上一節所說的NAF Nodes,如下圖),另一方面也是想說明在一些控制元件沒有固定的id、text和desc的時候,我們應該怎麼處理。
第三部分:點選 “好友動態”
要想操作一個控制元件(例如),首先得獲得一個UiObject物件,而UiObject物件可以通過UiSelector來構造,而UiSelector可以根據控制元件的id、text、content-desc來進行構造,這裡就是用content-desc來構造。
如上圖用 uiautomatorviewer 查到該控制元件的 content-desc 的內容是 “點選進入好友動態” ,因此我們就可以通過程式碼中的方法來得到UiObject物件了,然後呼叫click() 方法來達到點選效果。
第四部分:點選左上角返回按鈕
同第三部分的方法,找到id後直接獲得到UiObject物件,進行點選。
第五部分:點選選單鍵
UiDevice 可以模擬點選home、back、menu 這三個鍵,程式碼應該大家都懂的怎麼變化了吧。
第六部分:退出
這一部分也是先通過獲取出控制元件屬性中的text值,然後構造出UiObject物件,完成點選。
以上部分內容就是整個操作QQ這個小例子的全部程式碼講解,看完之後對寫Uiautomator程式碼有了更進一步的瞭解了吧。接下來寫看看還有哪些API可以支援我們做更多的事情。
API 列舉
UiDevice
概述:
UiDevice用與訪問關裝置狀態的資訊,也可以使用這個類來模擬使用者在裝置上的操作。可以通過下面的方法得到例項:
UiDevice mdevice = getUiDevice();
摘要:
函式返回值 | 函式體 | 說明 | 例項 |
boolean | click(int x, int y) | 模擬使用者在指定位置點選 | mdevice.click(200, 300) 點選螢幕的200,300座標處 |
String | getCurrentActivityName() | 獲得的是應用程式在桌面上顯示的名字 | 例如,在qq首頁得到的是“QQ”,在微信登入頁得到的是“微信”,注意,這個得到的不是Activity的名字 |
String | getCurrentPackageName() | 獲得當前顯示的應用程式的包名 | 例如,在微信啟動的時候,獲得的是“com.tencent.mm” |
int | getDisplayHeight() | 獲得當前裝置的螢幕解析度的高 | 例如,我的手機1920*1080,得到的是 1920 |
int | getDisplayWighth() | 獲得當前裝置的螢幕解析度的寬 | 例如,我的手機1920*1080,得到的是 1080 |
boolean | isScreenOn() | 判斷手機當前是否滅屏 | 當手機滅屏的時候,得到是“false”,手機亮屏,得到的是“true” |
void | wakeUp() | 點亮當前螢幕 | 呼叫後,相當於按下了電源鍵,如果手機設定了滑動鎖屏,滑動鎖屏還是在的,不會自動解開 |
boolean | pressBack() | 點選back鍵 | |
boolean | pressHome() | 點選home鍵 | |
boolean | pressMenu() | 點選menu鍵 | |
boolean | swipe(int startX, int startY, int endX, int endY, int steps) | 用指定的步長,從A點滑動B點 | 例如,需要從(10, 10)點用兩步滑動到(100, 200)點,則需要mdevice.swipe(10, 10, 100, 200, 2) |
boolean | takeScreenshot(File storePath) | 擷取當前螢幕,儲存到檔案 | 例如,File files = new File("/sdcard/res.jpg"); mdevice.takeScreenshot(files); 即可將截圖儲存到sd卡中了。 |
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("發"); |
比較常用,準確度也比較高,中文查詢的時候,如果遇到 “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、根據類:
UiSelector className(String className):
根據控制元件的類名來找到UiSelector物件。
但是呢?因為一般Android佈局的時候,同樣的控制元件類名都是一樣的。
因此我在微信的登入介面呼叫: UiSelector s = new UiSelector().className("android.widget.TextView") 這句話,它得到的就是我左上開始算第一個class名稱為“android.widget.TextView”的控制元件。
UiSelector instance (int instance):
上面提到的假如我們想獲取螢幕上電話號碼的那個TextView使用這樣方法,就可以使用instance:
UiSelector s = new UiSelector().className("android.widget.TextView").instance(1);
UiSelector index(int index):
用法和上面的instance差不多,谷歌的原文說這個方法是unreliable的,推薦使用instance方法。
UiSelector childSelector(UiSelector selector):
有的時候假如子控制元件不好獲得,而其父控制元件比較好獲得的時候,我們通常採用這樣的方式,例如下面:
我們目前選中的是LinearLayout,這個Android中的一種佈局,它的裡面嵌套了兩個控制元件,一個是ImageView,另一個是EditText。這們這裡就通過LinearLayout這個控制元件找到它的子控制元件。
很明顯,父控制元件id已經給定。我們先得到父控制元件:UiSelector s_p = new UiSelector().resourceId("com.tencent.mm:id/axj");
其次 UiSelector s_c= s_p.childSelector( new UiSelector().className("android.widget.EditText") );
在它的父控制元件的childSelector方法中傳入一個帶有一定特徵的UiSelector物件,即可得到子控制元件,這裡 s_c 就是輸入框的UiSelector物件。
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") );
5、根據特有屬性:
UiSelector | checked(boolean val) | 根據是否可check來構造出UiSelector物件 |
UiSelector | chickable(boolean val) | |
UiSelector | enabled(boolean val) | |
UiSelector | focusable(boolean val) | |
UiSelector | longClickable(boolean val) | |
UiSelector | scrollable(boolean val) | |
UiSelector | selected(boolean val) |
舉個簡單的例如,假如當前的介面,只有一個checkbox是勾選狀態,你就可以這樣得到:UiSelector s2 = new UiSelector().checked(true)
UiCollection
概述: 用的不多,直接參考文件
摘要: http://android.toolib.net/tools/help/uiautomator/UiCollection.html
UiScrollable
概述: 用的不多,直接參考文件
摘要: http://www.cnblogs.com/by-dream/p/4921701.html
UiObject
概述:可以理解為 直接操作介面ui元素的例項。
摘要:
返回值 |
函式 |
void |
ClearTextField() |
boolean |
click() |
boolean |
clickAndWaiForNewWindow(long timeout) |
boolean |
clickAndWaiForNewWindow() |
boolean |
clickBottomRight() |
boolean |
clickTopLeft() |
boolean |
exists() |
Rect |
getBounds() |
UiObject |
getChild(UiSelector selector) |
int |
getChildCount() |
String |
getContentDescription() |
UiObject |
getFromParent(UiSelector selector) |
String |
getPackageName() |
final UiSelector |
getSelector() |
String |
getText() |
Rect |
getVisibleBounds() |
boolean |
isCheckable() |
boolean |
isChecked() |
boolean |
isClickable() |
boolean |
isEnabled() |
boolean |
isFocused() |
boolean |
isLongClickable() |
boolean |
isScrollable() |
-
相關推薦
【Android測試】Uiautomator——API詳解
簡單的例子 以一個簡單的例子開始吧。我們完成一個 " 開啟QQ,進入QQ空間,然後退出 " 的case。 程式碼如下: package QQ; import java.io.IOException; impor
079:【Django資料庫】QuerySet API詳解-filter、exclude、annotate
QuerySet API詳解-filter、exclude、annotate: 在使用 QuerySet 進行查詢操作的時候,可以提供多種操作。比如過濾完後還要根據某個欄位進行排序,那麼這一系列的操作我們可以通過一個非常流暢的 鏈式呼叫 的方式進行。比如要從文章表中獲取標題為 123 ,並且提取後
【Android 動畫】View Animation詳解(一)
安卓平臺目前提供了兩大類動畫,在Android 3.0之前,一大類是View Animation,包括Tween animation(補間動畫),Frame animation(幀動畫),在android3.0中又引入了一個新的動畫系統:property ani
Android自定義View【實戰教程】5⃣️---Canvas詳解及程式碼繪製安卓機器人
友情連結: 神馬是Canvas 基本概念 Canvas:可以理解為是一個為我們提供了各種工具的畫布,我們可以在上面盡情的繪製(旋轉,平移,縮放等等)。可以理解為系統分配給我們一個一個記憶體空間,然後提供了一些對這個記憶體空間操作的方法(AP
Android自動化測試工具 UiAutomator使用詳解
1.介紹 Android團隊在4.1版本(API 16)中推出了一款全新的UI自動化測試工具UiAutomator,用來幫助開發人員更有效率的完成App的Debug工作,同時對於測試人員也是一大福音,為什麼這麼說呢? 測試:“我發現了一個b
【WebGL】WebGL API 詳解
基於 WebGL Specifications 最全面的API釋疑。 型別以及物件定義 這部分內容主要定義一部分型別和資料結構。 typedef unsigned long GLenum; typedef boolean GLboolean; typedef unsigned long G
【Android測試】UI自動化代碼優化之路
比較 互聯網產品 ref 註意 封裝 例子 成了 相對 tail 關於UI自動化的抱怨 聽過不少人這樣講 “UI自動化非常不穩定,需求一改,界面一遍,全部都費了”。我相信做過的人可能也會有同感。既然這個問題一直都是存在的,那麽為什麽沒有人仔細分析原因呢? 我的老板
【Android測試】【第十四節】Appium——簡述
ios 選擇 ive boot and tro jar appium tomato 前言 同樣的,這一篇我要介紹的也是一款UI自動化工具,地址:http://appium.io/ 第三方(非谷歌)研發的開源測試工具,說到這裏也許有人會問 “為什麽已經介紹了Ui
【Java日誌】log4j配置詳解
#設定日誌的級別,以及日誌所使用的appender log4j.rootLogger=all, console, file ### 控制檯 ### log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.cons
【深度學習】Tensorflow函式詳解
目錄 tf.truncated_normal tf.random_normal tf.nn.conv2d tf.nn.max_pool tf.reshape tf.nn.softmax tf.reduce_sum tf.reduce_max,tf.r
【C/C++】sizeof 關鍵字詳解
The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This
【SpringBoot系列】SpringBoot註解詳解
一、註解(annotations)列表 @SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration註解。其中@ComponentScan讓Spring Boot掃描到Con
【機器學習】XgBoost 原理詳解 數學推導
XgBoost (Xtreme Gradient Boosting 極限 梯度 增強) 1.基本描述: 假設Xg-模型有 t 顆決策樹數,t棵樹有序串聯構成整個模型,各決策樹的葉子節點數為 k1,k2,...,kt,
【機器學習】AdaBoost 原理詳解 數學推導
AdaBoost 自適應 增強 Boosting系列代表演算法,對同一訓練集訓練出不同的(弱)分類器,然後集合這些弱分類器構成一個更優效能的(強)分類器
【目標檢測】FastRCNN演算法詳解
摘自沈曉璐 有待補充自己的理解. 繼2014的RCNN之後,推出了FastRCNN ,構思精巧,流程更為緊湊,大幅提升了目標檢測的速度。 同樣使用最大規模的網路,FastRCNN 和RCNN相比,訓練時間從84小時減少為9.5小時,測試時間從47秒,減少為
【菜鳥】RESTful 架構詳解
RESTful 架構詳解 分類 程式設計技術 1. 什麼是REST REST全稱是Representational State Transfer,中文意思是表述(編者注:通常譯為表徵)性狀態轉移。 它首次出現在2000年Roy Fielding的博士論文中,Roy F
【Android測試】在AndroidStudio中進行單元測試
單元測試的流程 使用AndroidStudio進行單元測試時,與當前網上眾多資料進行比較。在較新版本下(當前我使用的是2.0)的studio中不需要自己進行BuildVariants的設定以及依賴JUnit包。studio會自動完成這些操作。 進行基
【深度學習】Inception層詳解
本文參考Torch的dpnn包中Inception層的原始碼,講解該模組引數含義以及網路結構。 核心思想 Inception模組的起點是類似下圖的結構:通道從M變換到N,把多個不同尺寸的卷積結果串接(concat)起來。 由於M,N往往很大,這種結
【資料結構】AVL樹詳解
1.什麼是AVL樹 AVL樹又稱平衡二叉搜尋樹,它能保證二叉樹高度相對平衡,儘量降低二叉樹的高度,提高搜尋效率。單純的二叉搜尋樹在最壞的情況下插入查詢刪除等操作時間複雜度會是O(N), 例如: 所以,AVL樹就能避免這種情況,使得增刪查改的時間複雜度為O(lgN). (p
【網路程式設計】滑動視窗詳解 (TCP流量控制)
滑動視窗 (TCP流量控制) 介紹UDP時我們描述了這樣的問題:如果傳送端傳送的速度較快,接收端接收到資料後處理的速度較慢,而接收緩衝區的大小是固定的,就會丟失資料。TCP協議通過“滑動視窗(Slid