Android 测试支持库提供了大量用于测试 Android 应用的框架。此库提供了一组 API,让您可以为应用快速构建何运行测试代码,包括 JUnit 4 和功能性用户界面 (UI) 测试。您可以从 Android Studio IDE 或命令行运行使用这些 API 创建的测试。
Android 测试支持库通过 Android SDK 管理器提供。
Android 测试支持库包括以下自动化测试工具:
AndroidJUnitRunner:适用于 Android 且与 JUnit 4 兼容的测试运行器
Espresso:UI 测试框架;适合应用中的功能性 UI 测试
UI Automator:UI 测试框架;适合跨系统和已安装应用的跨应用功能性 UI 测试
AndroidJUnitRunner
AndroidJUnitRunner 类是一个 JUnit 测试运行器,可让您在 Android 设备上运行 JUnit 3 或 JUnit 4 样式测试类,包括使用 Espresso 和 UI Automator 测试框架的设备。测试运行器可以将测试软件包和要测试的应用加载到设备、运行测试并报告测试结果。此类将替换 InstrumentationTestRunner 类,后者仅支持 JUnit 3 测试。
此测试运行器的主要功能包括:
JUnit 支持
访问仪器信息
测试筛选
测试分片
Espresso
Espresso 测试框架提供了一组 API 来构建 UI 测试,用于测试应用中的用户流。利用这些 API,您可以编写简洁、运行可靠的自动化 UI 测试。Espresso 非常适合编写白盒自动化测试,其中测试代码将利用所测试应用的实现代码详情。
Espresso 测试框架的主要功能包括:
灵活的 API,用于目标应用中的视图和适配器匹配。
一组丰富的操作 API,用于自动化 UI 交互。
UI 线程同步,用于提升测试可靠性。
视图匹配
利用 Espresso.onView() 方法,您可以访问目标应用中的 UI 组件并与之交互。此方法接受 Matcher 参数并搜索视图层次结构,以找到符合给定条件的相应 View 实例。您可以通过指定以下条件来优化搜索:
视图的类名称
视图的内容描述
视图的 R.id
在视图中显示的文本
例如,要找到 ID 值为 my_button 的按钮,可以指定如下匹配器:
onView(withId(R.id.my_button));如果搜索成功,onView() 方法将返回一个引用,让您可以执行用户操作并基于目标视图对断言进行测试。
适配器匹配
在 AdapterView 布局中,布局在运行时由子视图动态填充。如果目标视图位于某个布局内部,而该布局是从 AdapterView(例如 ListView 或 GridView)派生出的子类,则 onView() 方法可能无法工作,因为只有布局视图的子集会加载到当前视图层次结构中。
因此,请使用 Espresso.onData() 方法访问目标视图元素。Espresso.onData() 方法将返回一个引用,让您可以执行用户操作并根据 AdapterView 中的元素对断言进行测试。
操作 API
通常情况下,您可以通过根据应用的用户界面执行某些用户交互来测试应用。借助 ViewActions API,您可以轻松地实现这些操作的自动化。您可以执行多种 UI 交互,例如:
视图点击
滑动
按下按键和按钮
键入文本
打开链接
例如,要模拟输入字符串值并按下按钮以提交该值,您可以像下面一样编写自动化测试脚本。ViewInteraction.perform() 和 DataInteraction.perform() 方法采用一个或多个 ViewAction 参数,并以提供的顺序运行操作。
// Type text into an EditText view, then close the soft keyboard
onView(withId(R.id.editTextUserInput))
.perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard());
// Press the button to submit the text change
onView(withId(R.id.changeTextBt)).perform(click());
UI 线程同步
由于计时问题,Android 设备上的测试可能随机失败。此测试问题称为测试不稳定。在 Espresso 之前,解决方法是在测试中插入足够长的休眠或超时期或添加代码,以便重试失败的操作。Espresso 测试框架可以处理 Instrumentation 与 UI 线程之间的同步;这就消除了对之前的计时解决方法的需求,并确保测试操作与断言更可靠地运行。
UI Automator
UI Automator 测试框架提供了一组 API 来构建 UI 测试,用于在用户应用和系统应用中执行交互。利用 UI Automator API,您可以执行在测试设备中打开“设置”菜单或应用启动器等操作。UI Automator 测试框架非常适合编写黑盒自动化测试,其中的测试代码不依赖于目标应用的内部实现详情。
UI Automator 测试框架的主要功能包括:
用于检查布局层次结构的查看器。
在目标设备上检索状态信息并执行操作的 API。
支持跨应用 UI 测试的 API。
UI Automator 查看器
uiautomatorviewer 工具提供了一个方便的 GUI,可以扫描和分析 Android 设备上当前显示的 UI 组件。您可以使用此工具检查布局层次结构,并查看在设备前台显示的 UI 组件属性。利用此信息,您可以使用 UI Automator(例如,通过创建与特定可见属性匹配的 UI 选择器)创建控制更加精确的测试。
uiautomatorviewer 工具位于 /tools/ 目录中。
访问设备状态
UI Automator 测试框架提供了一个 UiDevice 类,用于在目标应用运行的设备上访问和执行操作。您可以调用其方法来访问设备属性,如当前屏幕方向或显示尺寸。UiDevice 类还可用于执行以下操作:
更改设备旋转
按 D-pad 按钮
按“返回”、“主屏幕”或“菜单”按钮
打开通知栏
对当前窗口进行屏幕截图
例如,要模拟按下“主屏幕”按钮,请调用 UiDevice.pressHome() 方法。
UI Automator API
利用 UI Automator API,您可以编写稳健可靠的测试,而无需了解目标应用的实现详情。您可以使用这些 API 在多个应用中捕获和操作 UI 组件:
UiCollection:枚举容器的 UI 元素以便计算子元素个数,或者通过可见的文本或内容描述属性来指代子元素。
UiObject:表示设备上可见的 UI 元素。
UiScrollable:为在可滚动 UI 容器中搜索项目提供支持。
UiSelector:表示在设备上查询一个或多个目标 UI 元素。
Configurator:允许您设置运行 UI Automator 测试所需的关键参数。
例如,以下代码显示了如何编写可在设备中调用默认应用启动器的测试脚本:
// Initialize UiDevice instance
mDevice = UiDevice.getInstance(getInstrumentation());
// Perform a short press on the HOME button
mDevice.pressHome();
// Bring up the default launcher by searching for
// a UI component that matches the content-description for the launcher button
UiObject allAppsButton = mDevice
.findObject(new UiSelector().description("Apps"));
// Perform a click on the button to bring up the launcher
allAppsButton.clickAndWaitForNewWindow();
测试支持库设置
要将 AndroidJUnitRunner 设置为 Gradle 项目中的默认测试仪器运行器,请在 build.gradle 文件中指定此依赖关系:
android {
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}整体配置
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.ocrapp"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
//设定gradle默认测试环境
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
useLibrary 'android.test.runner'
useLibrary 'android.test.base'
useLibrary 'android.test.mock'
}
dependencies {
//test
testImplementation 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.1.4"
testImplementation 'androidx.test:core:1.1.0'
testImplementation 'androidx.test.ext:junit:1.1.0'
testImplementation 'androidx.test:runner:1.1.2-alpha02'
testImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02'
}