Android自動化測試工具 UiAutomator使用詳解
1.介紹
Android團隊在4.1版本(API 16)中推出了一款全新的UI自動化測試工具UiAutomator,用來幫助開發人員更有效率的完成App的Debug工作,同時對於測試人員也是一大福音,為什麼這麼說呢?
測試:“我發現了一個bug,你寫的App開啟A頁面,再開啟B頁面有時會出現閃屏問題。”
開發:“嗯?還有這樣的問題,復現給我看看。(內心獨白:我寫的App怎麼會有bug,一定是你用的姿勢不對)”
測試:一段忙碌的操作之後…“咦,怎麼不出現了?”
開發:“那你先回去吧,復現再告訴我。”
幾天過去了…
測試:滿心歡喜狀,“上次那個問題我復現了,操作給你看….我去,怎麼又不出現了!”
開發:“是不是裝置有問題,你換個裝置再試試呢?”
測試:“寶寶心裡苦,但是寶寶不說!”
有了UiAutomator之後:
測試:“我發現了一個bug,你寫的App開啟A頁面,再開啟B頁面有時會出現閃屏問題。”
開發:“這個簡單,我用UiAutomator寫個測試用例,分分鐘解決。”
測試:“厲害了Word哥!”
全劇終!
UiAutomator提供了以下兩種工具來支援UI自動化測試:
-
uiautomatorviewer:用來分析UI控制元件的圖形介面工具,位於SDK目錄下的tools資料夾中。
-
uiautomator:一個java庫,提供執行自動化測試的各種API。
2.環境搭建
本文使用了Android Studio作為IDE,Eclipse,Please go home!
首先在app根目錄的build.gradle檔案中加入依賴:
// AS預設配置,如果如果沒有記得加上androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group:'com.android.support', module: 'support-annotations'}) androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
注意:uiautomator庫支援的最低版本為API 18,所以本篇文章開發環境的minSdkVersion為18。
配置testInstrumentationRunner為AndroidJunitRunner:
defaultConfig { ... // 這個AS會為我們預設配置,如果沒有記得加上 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"}
看下完整的build.gradle檔案:
apply plugin: 'com.android.application'android { compileSdkVersion 25 buildToolsVersion "25.0.3" defaultConfig { applicationId "com.yl.uiautomatordemo" minSdkVersion 18 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' testCompile 'junit:junit:4.12' androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2' }
在dependencies中用到了compile、testCompile、androidTestCompile三種依賴方式,讓我們來看看他們有什麼區別:
-
compile:參與編譯,並且會打包到debug/release apk中。
-
testCompile:只參與單元測試編譯,不會打包到debug/release apk包中,不需要裝置支援。
-
androidTestCompile:只參與UI測試編譯,不會打包到debug/release apk包中,需要裝置支援。
除此之外還有Provided、APK、Debug compile和Release compile:
-
Provided:只參與編譯,不會打包到debug/release apk中。
-
APK:不參與編譯,只會打包到debug/release apk中。
-
Debug compile:只參與debug編譯,只會打包到debug apk中。
-
Release compile:只參與release編譯,只會打包到release apk中。
3.測試流程
-
1.安裝被測試App到手機中。
-
2.開啟UI分析工具uiautomatorviewer.bat,分析當前UI的介面元素,確保App的各個控制元件可以被測試工具獲取到。
-
3.根據App使用流程編寫測試用例。
-
4.執行測試用例進行測試,定位bug,解決bug。
4.實踐
以《可摺疊的Toolbar—CollapsingToolbarLayout》中的Demo為例,假設反覆滑動佈局會導致應用crash,針對這種情況,我們來寫一個測試用例:
分析UI的介面元素
啟動被測試App,開啟uiautomatorviewer.bat工具,點選左上角的Device Screenshot按鈕捕獲螢幕快照,如下圖所示,左側顯示螢幕快照,右側顯示佈局結構與控制元件屬性,控制元件屬性在編寫測試用例時會用到。
編寫測試用例
選擇File—New—New Project新建專案,和建立普通專案的流程相同,只不過不需要建立Activity,建立完成後,專案結構如下圖所示:
可以看到,在app—src目錄下,AS為我們自動建立了一個androidTest資料夾,用來編寫UI測試用例,同級還有一個test資料夾,用來編寫單元測試用例。
專案建立成功後,參考上文引入依賴,構建完成後,開始寫測試用例吧!等等,先別急,在此之前先普及一下uiautomator的常用API:
-
UiDevice:
裝置物件,通過UiDevice的getInstance(instrumentation)方法獲取,可以通過UiDevice例項來檢測裝置的各種屬性,比如獲取螢幕的方向、尺寸等,還可以通過UiDevice例項來執行裝置級別的操作,比如點選Home鍵、返回鍵等:
// 點選Home鍵uiDevice.pressHome();// 點選返回鍵uiDevice.pressBack();
...
-
UiSelector
用於獲取某些符合條件的UI控制元件物件,可以通
// 通過資源id獲取new UiSelector().resourceId("com.yang.designsupportdemo:id/CollapsingToolbarLayout");
// 通過描述檔案獲取new UiSelector().description("Navigate up")// 通過className獲取new UiSelector().className("android.support.v7.widget.RecyclerView") ...
-
UiObject
代表一個UI控制元件,通過uiDevice的findObject(UiSelector)方法獲取,獲取到UiObject例項後,就可以對UI控制元件進行相關的操作,比如點選、長按等:
// 點選應用返回按鈕UiObject back = uiDevice.findObject(new UiSelector().description("Navigate up")); back.click();
-
UiCollection
代表UI控制元件集合,相當於ViewGroup,比如介面中有多個CheckBox時,可以通過類名獲取到當前介面下的所有CheckBox,然後通過控制元件id獲取指定的CheckBox物件:
// 獲取指定的CheckBox物件UiCollection uiCollection = new UiCollection(new UiSelector().className("類名")); UiObject checkBox = uiCollection.getChild(new UiSelector().resourceId(""));
-
UiScrollable
代表可滾動的控制元件,比如開啟設定的關於手機選項:
// 滑動列表到最後,點選About phone選項UiScrollable settings = new UiScrollable(new UiSelector().className("android.support.v7.widget.RecyclerView")); UiObject about = settings.getChildByText(new UiSelector().className("android.widget.LinearLayout"), "About phone"); about.click();
看下滾動效果:
OK,常用API到這裡就說的差不多了,開始寫測試用例吧!
Talk is cheap, Show me the code.
public class UiTest extends TestCase { public void testA() throws UiObjectNotFoundException { // 獲取裝置物件 Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); UiDevice uiDevice = UiDevice.getInstance(instrumentation); // 獲取上下文 Context context = instrumentation.getContext(); // 啟動測試App Intent intent = context.getPackageManager().getLaunchIntentForPackage("com.yang.designsupportdemo"); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(intent); // 開啟CollapsingToolbarLayout String resourceId = "com.yang.designsupportdemo:id/CollapsingToolbarLayout"; UiObject collapsingToolbarLayout = uiDevice.findObject(new UiSelector().resourceId(resourceId)); collapsingToolbarLayout.click(); for (int i = 0; i < 5; i++) { // 向上移動 uiDevice.swipe(uiDevice.getDisplayHeight() / 2, uiDevice.getDisplayHeight(), uiDevice.getDisplayHeight() / 2, uiDevice.getDisplayHeight() / 2, 10); // 向下移動 uiDevice.swipe(uiDevice.getDisplayHeight() / 2, uiDevice.getDisplayHeight() / 2, uiDevice.getDisplayHeight() / 2, uiDevice.getDisplayHeight(), 10); } // 點選應用返回按鈕 UiObject back = uiDevice.findObject(new UiSelector().description("Navigate up")); back.click(); // 點選裝置返回按鈕 uiDevice.pressBack(); } }
程式碼中寫了很全的註釋,簡單說下,首先獲取裝置物件和上下文,這個後面要用到,然後啟動測試App,開啟需要測試的介面,上下滑動5次後退出App,由於上文中對API已經有了一定了解,看起程式碼來還是很輕鬆的。
注意:測試方法需要以test開頭,如果存在多個測試方法,以test後的字母順序執行。
程式碼寫完了,接下來就要開始測試了,右擊測試類選擇Run按鈕,或者點選測試類中的執行按鈕進行測試,上面的按鈕代表執行所有測試方法,下面的按鈕代表只執行當前測試方法:
測試執行後,可以看到控制檯上列印了一些資訊:
可以看到,首先通過adb shell命令在裝置中安裝了UiAutomatorDemo和com.yl.uiautomatordemo.test兩個apk,然後啟動測試,此時被測App已經開始執行測試流程,執行完成後,顯示測試結果,看下App的執行效果:
OK,到這裡,UiAutomator的基本用法就講完了。
最後
如果對測試框架感興趣小楓這推薦一個群,裡面自動化測試,面試寶典,測試框架等等,進群免費領取喲,1140267353
掃碼進群有驚喜,等待大家的加入這個大家庭!!!