原文位址:Automating User Interface Testing on Android
介紹
Android的Testing Support library中包含了UI 自動化架構,它主要是用于做Android應用的黑盒自動化測試,在API18上,這個測試架構允許開發者在組成應用UI的控件上進行模拟使用者的操作。
在這次教程中,我将展示給你如何使用這個測試架構,以及建立并運作。對預設的電腦應用進行基本UI測試。
先決條件
在使用前,你需要:
- 最新版本的Android Studio
- 一個Android 4.3或者更高版本的裝置或模拟器
- JUnit的基本概念
1. 安裝依賴項
為了能夠在你的項目中使用UI自動化測試架構。在你的項目的app目錄下編輯build.gradle.增加下面的依賴項:
androidTestCompile 'com.android.support.test:runner:0.2'
androidTestCompile 'com.android.support.test:rules:0.2'
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.0'
“Sync Now”的按鈕會顯示在螢幕上,當你點選時,你将會看到一個錯誤,像下面這樣:
點選 Install Repository and sync project 連結,将會去安裝Android Support Repository.
如果你使用了 appcompat-v7的庫并且它的版本是22.1.1時,你需要增加一下的一個依賴來確定你的應用以及你測試的應用都是使用的同樣版本的
com.android.support:support-annotations
:
androidTestCompile 'com.android.support:support-annotations:22.1.1'
再下來,由于Android Studio的一個bug, 你需要使用
packagingOptions
來執行一個叫LICENSE.txt 的檔案,是以當你嘗試去運作測試時,将會導緻你如下的失敗資訊:
Execution failed for task ':app:packageDebugAndroidTest'.
Duplicate files copied in APK LICENSE.txt
File : ~/.gradle/caches/modules-2/files-/org.hamcrest/hamcrest-core//d1a344907ac75754e259cdb14/hamcrest-core-.jar
File : ~/.gradle/caches/modules-2/files-/junit/junit-dep//b3bafdecd366afa514bd5beeae6c1f85ece/junit-dep-.jar
在你的build.gradle檔案的底部新增如下一小段:
android {
packagingOptions {
exclude 'LICENSE.txt'
}
}
2. 建立一個測試類
建立一個新的測試類,
CalculatorTester
通過在androidTest的目錄下建立一個叫CalculatorTester.javade檔案。為來建立一個UI 自動化測試用例,你的類必須繼承
InstrumentationTestCase
.
按下 Alt+Insert鍵,然後點選SetUp 方法對
setUp
方法進行重寫
再次按下 Alt+Insert 點選Test Method 生成一個新的測試方法,名字為
testAdd
,
CalculatorTester
這個類就像下面這樣:
public class CalculatorTester extends InstrumentationTestCase{
@Override
public void setUp() throws Exception {
}
public void testAdd() throws Exception {
}
}
檢視 Launcher的UI
将你的Android 裝置連結到你的電腦上,并且點選裝置上的Home鍵傳回到桌面。
回到你的電腦,使用一個檔案浏覽器或者一個終端進入到你安裝Android SDK的路徑下,下一步,進入到tools目錄下,啟動 uiautomatorviewer, 它将會啟動一個UI Automator Viewer. 螢幕顯示的就像這樣:
點選那個像手機的按鈕對你的Android 裝置進行截圖,注意你剛才的截屏是可互動的,點選底部的App圖示,在右邊 Node Detail區域,你将會看到你選擇區域的各個詳細的變量就如下面顯示的:
為了能夠與螢幕上的應用互動,UI自動化測試架構需要有一個唯一的辨別來識别他們,在這次的教程中,你可以使用
text
也可以使用
content-desc
或者說
class
去唯一的識别它。
正如你看到的,應用的圖示沒有任何的
text
,但是它有一個
content-desc
,對這個值做個紀錄,因為我們下一步将會用到它。
現在,拿起你的Android裝置,點選螢幕上的應用圖示,進入裝置安裝的所有應用界面。使用 UI Automater Viewe 擷取另外一張螢幕截圖。因為要寫一個電腦應用的測試,點選電腦圖示檢視詳細界面。
這個時候,
content-desc
的内容是空的,但是
text
的内容為Calculator.同樣對這個也做個記錄。
如果你的Android裝置運作着不同的launcher 或者不同的Android 版本, 截屏以及node detail都将會不同,這也就意味你需要修改你的代碼去比對作業系統。
4. 準備測試環境
回到Android Studio 中,在
setUp
方法中添加代碼,正如它名字的提示一樣,
setUp
方法用來準備你的測試環境,換句話說,它會執行一些你真正進行測試前所需要特别完成的内容。
下來你将編寫代碼模拟之前你在Android裝置上做的操作:
1. 按下home鍵傳回到主螢幕
2. 點選 應用圖示進入所有應用中
3. 通過點選Calculator 應用啟動它
在你的類中,聲明一個叫
device
的
UiDevice
類型的成員變量,這個變量代表來你的Android 裝置,并且你講通過它模拟UI操作。
private UiDevice device;
在
setUp
方法中,通過調用
UiDevice.getinstance
方法來對device進行初始化,就如下面一樣傳遞一個
Instrumentation
的執行個體參數
device = UiDevice.getInstance(getInstrumentation());
調用
pressHome
方法模拟按下裝置的Home鍵
device.pressHome()
下來,你需要在應用的圖示上模拟點選事件,但你不能夠立即這麼做,因為你的Android 裝置需要一會兒的時間在加載界面,在它顯示在螢幕之前嘗試去點選應用圖示的會,它将會抛出一個runtime的異常。
為來等待某個事情的發生,你需要調用
UiDevice
執行個體對象的
wait
方法,使用
Until.hasObject
方法等待應用的圖示顯示在螢幕上。
為來能夠識别出應用的圖示,使用
By.des
方法,并傳遞Apps作為參數。你還需要說明等待的最大毫秒數,這裡設定為3000,結果就像下面的代碼:
// Wait for the Apps icon to show up on the screen
device.wait(Until.hasObject(By.desc("Apps")), );
為來擷取應用圖示的引用,使用
findObject
方法,一旦你擷取到來應用圖示的應用,調用
click
方法模拟點選。
UiObject2 appsButton = device.findObject(By.desc("Apps"));
appsButton.click();
就跟前面一樣,你需要等待一會,讓Calculator的圖示顯示到螢幕上,你能夠看到Calculator 的圖示能夠通過它的
text
變量被唯一識别出來,我們調用
By.text
方法,傳遞
Calculator
參數來找到圖示
// Wait for the Calculator icon to show up on the screen
device.wait(Until.hasObject(By.text("Calculator")), );
使用
findObject
和
click
方法擷取到 Calculator圖示的引用,模拟點選
UiObject2 calculatorApp = device.findObject(By.text("Calculator"));
calculatorApp.click();
5.檢視Calculator的UI
在你的Android裝置上運作Calculator應用,并且通過Ui Autoamtor Viewer去檢視它,在擷取截圖後,點選這些按鈕,看看是否能夠唯一的識别他們。
這次的測試用例是,你将操作電腦計算 9+9 并且檢查結果是否為18。這就意味着你必須要知道如何識别出9,+和=。
在我的裝置上,如下是我收集到的資訊:
- 數字按鍵比對text值
- + 和 = 使用content-desc值,分别對應 plus 和 equals
- 傳回值顯示在EditText控件中
注意如果你使用不同版本的Calculator應用的話,這些值可能會不一樣在你的裝置上。
6. 建立測試用例
在前面的步驟中,你已經學會了通過使用
findObject
同時使用
By.text
或
By.desc
擷取螢幕上的任何對象引用,你也知道了使用
click
方法去模拟點選對象,在
CalculatorTester
類的
testAdd
方法中添加如下的代碼,進行9+9=的操作。
// Wait till the Calculator's buttons are on the screen
device.wait(Until.hasObject(By.text("9")), );
// Select the button for 9
UiObject2 buttonNine = device.findObject(By.text("9"));
buttonNine.click();
// Select the button for +
UiObject2 buttonPlus = device.findObject(By.desc("plus"));
buttonPlus.click();
// Press 9 again as we are calculating 9+9
buttonNine.click();
// Select the button for =
UiObject2 buttonEquals = device.findObject(By.desc("equals"));
buttonEquals.click();
這個時候,你需要等待結果,然而,你不能夠在這裡使用
Until.hasObject
,因為在螢幕上
EditText
已經包含了結果,相反的你需要使用
waitForIdle
方法等待結算完成,再來設定3000ms作為最大的等待時間,
device.waitForIdle();
通過使用
findObject
和
By.clazz
方法,擷取到
EditText
對象的引用,一旦你獲得到了它的引用,就可以調用
getText
方法來擷取到計算的結果。
UiObject2 resultText = device.findObject(By.clazz("android.widget.EditText"));
String result = resultText.getText();
最後,使用
assertTrue
驗證結果是否為18
assertTrue(result.equals("18"));
你的測試用例就算是完成來
7 運作測試用例
執行測試需要在Android Studio的工具條下拉框中選擇
CalculatorTester
并在它右邊點選播放按鈕
一旦編譯完成,測試将會運作并且成功執行完成,當測試用例執行時,你将能夠看到你的Android裝置在執行自動化
結論
在這次的教程中,你學習了如何使用UI的自動化測試架構和Ui Automator Viewer 去建立一個UI 測試,你也能夠看到使用Android Studio進行測試時如此的簡單,盡管我們測試的事一個相當簡單的應用,但你能夠應用你在這裡學習到的内容去測試大部分的Android應用。
你可以在 Android Developers websites中學習更多有關于 testing support library的内容