介绍
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 1: ~/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.1/860340562250678d1a344907ac75754e259cdb14/hamcrest-core-1.1.jar
File 2: ~/.gradle/caches/modules-2/files-2.1/junit/junit-dep/4.10/64417b3bafdecd366afa514bd5beeae6c1f85ece/junit-dep-4.10.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")), 3000);
为来获取应用图标的引用,使用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")), 3000);
使用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")), 3000);
// 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(3000);
通过使用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的内容