本文档介绍了如何直接通过命令行运行测试。本文假定您已经知道如何创建 Android 应用并为应用编写测试。如需详细了解如何为应用构建测试,请参阅在 Android 平台上测试应用。
当您使用 Gradle 构建系统构建应用时,Android Gradle 插件可让您使用命令行从 Gradle 项目运行测试。若想实现更精细的控制,您还可以选择通过 Android 调试桥 (adb) shell 运行测试。
使用 Gradle 运行测试
借助 Android Gradle 插件,您可以使用命令行从 Gradle 项目运行测试。
下表总结了如何使用 Gradle 运行测试:
表 1. 使用 Gradle 运行测试的不同方法。
单元测试类型 | 要运行的命令 | 测试结果所在的位置 |
---|---|---|
本地单元测试 |
运行 test 任务:
|
HTML 测试结果文件:path_to_your_project/module_name/build/reports/tests/ 目录。
XML 测试结果文件: |
插桩单元测试 |
运行 connectedAndroidTest 任务:
|
HTML 测试结果文件:path_to_your_project/module_name/build/reports/androidTests/connected/ 目录。
XML 测试结果文件: |
Gradle 支持任务名称缩写。这意味着,如果您输入以下命令,便可启动 connectedAndroidTest
任务。
./gradlew cAT
您还可以选择运行 Gradle 任务 check
和 connectedCheck
。这些任务分别运行您的本地测试或插桩测试,但还包含其他 Gradle 插件添加的其他检查。
在模块上运行测试
test
和 connectedAndroidTest
任务会在项目中的每个模块上运行测试。您可以在测试或 connectedAndroidTest
任务前加上模块名称和英文冒号 (:),仅针对项目中的特定模块运行测试。例如,以下命令仅针对 mylibrary
模块运行插桩单元测试。
./gradlew mylibrary:connectedAndroidTest
对 build 变体运行测试
test
和 connectedAndroidTest
任务会针对项目中的每个 build 变体运行测试。您可以使用以下语法定位特定的 build 变体。
- 对于本地单元测试:
./gradlew testVariantNameUnitTest
- 对于插桩测试:
./gradlew connectedVariantNameAndroidTest
运行特定的测试方法或类
运行本地单元测试时,您还可以针对 Gradle 使用 --tests
标记定位特定的测试。例如,以下命令仅针对指定的 build 变体运行 sampleTestMethod
测试。要详细了解如何使用 --tests
标记,请参阅关于测试过滤的 Gradle 文档。
./gradlew testVariantNameUnitTest --tests '*.sampleTestMethod'
针对插桩测试的多模块报告
如表 1 所述,Gradle 会将插桩测试结果保存在它测试的每个模块的 build/
目录中。但是,在对多个模块运行测试时,将所有测试结果合并到一个报告中可能很有用。要在对多个模块运行测试时生成一个报告,请按以下步骤操作:
在项目级
build.gradle
文件中,在buildscript{}
代码块后添加以下代码:Groovy
apply plugin 'android-reporting'
Kotlin
apply(plugin = "android-reporting")
使用
mergeAndroidReports
任务调用test
或connectedAndroidTest
任务。例如:./gradlew connectedAndroidTest mergeAndroidReports
如果要跳过测试失败的情况以便让 Gradle 运行完所有剩余测试,请添加
--continue
选项:./gradlew connectedAndroidTest mergeAndroidReports --continue
当 Gradle 运行完所有测试后,它会将合并的结果保存在 path_to_your_project/build/
目录中。
使用 adb 运行测试
当您使用 Android 调试桥 (adb) 从命令行运行测试时,您可以获得比任何其他方法更多的选项来选择要运行的测试。您可以选择单独的测试方法,根据自定义注解筛选测试,或指定测试选项。由于测试任务完全由命令行控制,因此您可以通过各种方式使用 Shell 脚本自定义测试。
若想通过命令行运行测试,请运行 adb shell
以在设备或模拟器上启动命令行 shell。在该 shell 中,您可以使用 am
命令与 Activity 管理器进行交互,并使用其 instrument
子命令运行测试。
作为一种快捷方式,您可以在同一个输入行上启动 adb shell,调用 am instrument
和指定命令行 flag。shell 会在设备或模拟器上打开,运行测试,生成输出,然后返回到计算机上的命令行。
要使用 am instrument
运行测试,请执行以下操作:
- 构建或重新构建主应用和测试软件包。
- 将测试软件包和主应用 Android 软件包文件(APK 文件)安装到当前的 Android 设备或模拟器中
在命令行中,输入:
adb shell am instrument -w <test_package_name>/<runner_class>
其中,
<test_package_name>
是测试应用的 Android 软件包名称,<runner_class>
是您正在使用的 Android 测试运行程序类的名称。Android 软件包名称是测试软件包的清单文件 (AndroidManifest.xml
) 中清单元素的软件包属性的值。Android 测试运行程序类通常是AndroidJUnitRunner
:adb shell am instrument -w com.android.foo/androidx.test.runner.AndroidJUnitRunner
测试结果会显示在 STDOUT
中。
am instrument 标记
您可以通过运行 adb shell am help
找到与 am instrument
命令搭配使用的所有标记的列表。下表介绍了一些重要标记:
表 2. 重要的 am instrument 标记。
标记 | 值 | 说明 |
---|---|---|
-w
|
(无) |
强制 am instrument 一直等到插桩终止后再终止自身。实际影响是在测试完成前使 shell 一直保持打开状态。必须使用此标记,才能看到测试结果。
|
-r
|
(无) |
原始格式的输出结果。如果要收集性能测量值,请使用此标记,这样系统就不会将它们的格式设置为测试结果。此标记应与 -e perf true 标记(如 am rurument options 部分中所述)一起使用。
|
-e
|
<test_options> |
提供键值对形式的测试选项。am instrument 工具会通过其 onCreate() 方法将这些选项传递给指定的插桩类。您可以指定 -e <test_options> 多次。键和值在 am instrument 选项部分中进行了介绍。您只能将这些键值对用于 AndroidJUnitRunner 或 InstrumentationTestRunner 及其子类。将这些键值对用于任何其他类没有任何作用。
|
--no-hidden-api-checks
|
(无) | 停用对使用隐藏 API 的限制。如需详细了解什么是隐藏 API 及其对您的应用产生的影响,请参阅对非 SDK 接口的限制。 |
am instrument 选项
am instrument 工具使用 -e
标记以键值对的形式将测试选项传递给 AndroidJUnitRunner
或 InstrumentationTestRunner
,语法如下:
-e <key> <value>
某些键接受多个值。您可以在英文逗号分隔列表中指定多个值。例如,以下 AndroidJUnitRunner
调用为 package
键提供了多个值:
adb shell am instrument -w -e package com.android.test.package1,com.android.test.package2 \
> com.android.test/android.support.test.runner.AndroidJUnitRunner
下表列出了可针对测试运行程序使用的键值对。
表 3. 可与测试运行程序搭配使用的 -e 标记键值对。
键 | 值 | 说明 |
---|---|---|
package
|
<Java_package_name> | 测试应用中某个软件包的完全限定 Java 软件包名称。系统会执行使用此软件包名称的所有测试用例类。请注意,这不是 Android 软件包名称;测试软件包只有一个 Android 软件包名称,但其中可能包含多个 Java 软件包。 |
class |
<class_name> | 其中一个测试用例类的完全限定 Java 类名称。系统仅会执行此测试用例类。 |
<class_name>#method name | 完全限定测试用例类名称及其方法之一。系统仅会执行此方法。注意类名和方法名之间的哈希标记 (#)。 | |
func |
true |
运行扩展 InstrumentationTestCase 的所有测试类。
|
unit |
true |
运行没有扩展 InstrumentationTestCase 或 PerformanceTestCase 的所有测试类。
|
size |
[small | medium | large ]
|
运行按大小注解的测试方法。注解为 @SmallTest 、@MediumTest 和 @LargeTest 。
|
perf |
true |
运行所有实现 PerformanceTestCase 的测试类。使用此选项时,还要为 am instrument 指定 -r 标记,以原始格式保存输出,而不重新调整为测试结果。
|
debug |
true |
在调试模式下运行测试。 |
log |
true |
加载并记录所有指定的测试,但不运行它们。测试信息会显示在 STDOUT 中。使用此选项可验证其他过滤器和测试规范的组合。
|
emma |
true |
运行 EMMA 代码覆盖率分析并将输出写入设备上的 /data/<app_package>/coverage.ec 。要替换文件位置,请使用以下条目中所述的 coverageFile 键。
注意:此选项需要对测试应用进行 EMMA 插桩 build,您可以使用 |
coverageFile |
<filename> |
替换设备上 EMMA 覆盖率文件的默认位置。将此值指定为 UNIX 格式的路径和文件名。emma 键的条目中描述了默认文件名。
|
使用 -e
标记时,请注意以下事项:
am instrument
会在调用onCreate(Bundle)
时传入包含键值对的Bundle
。package
键优先于class
键。如果您指定了一个软件包,然后在该软件包中单独指定一个类,Android 将运行该软件包中的所有测试并忽略类键。func
键和unit
键是互斥的。
用法示例
以下部分提供了使用 am instrument
运行测试的示例。它们基于以下结构:
- 测试软件包的 Android 软件包名称为
com.android.demo.app.tests
- 两个插桩测试类:
Foo1
(包含测试方法bar1
)和Foo2
(包含测试方法bar2
和bar3
)
- 测试运行程序为
AndroidJUnitRunner
。
运行整个测试软件包
要运行测试软件包中的所有测试类,请输入:
adb shell am instrument -w com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner
运行测试用例类中的所有测试
要运行 Foo1
类中的所有测试,请输入:
adb shell am instrument -w \
> -e class com.android.demo.app.tests.Foo1 \
> com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner
选择一部分测试
如需运行 Foo1
类中的所有测试以及 Foo2 中的 bar3 方法,请输入:
adb shell am instrument -w \
> -e class com.android.demo.app.tests.Foo1,com.android.demo.app.tests.Foo2#bar3 \
> com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner
您可以在 AndroidJUnitRunner
API 参考文档中找到更多用例。