Gradle 管理的设备可提高自动化插桩测试的一致性、性能和可靠性。此功能适用于 API 级别 27 及更高版本,可让您在项目的 Gradle 文件中配置虚拟或远程实体测试设备。构建系统使用这些配置在执行自动化测试时全面管理(即创建、部署和拆解)这些设备。
此功能使 Gradle 不仅能了解您正在运行的测试,还能了解设备的生命周期,从而通过以下方式提高测试体验的质量
- 处理设备相关问题,以确保您的测试得以执行
- 对于虚拟设备,使用模拟器快照缩短设备启动时间并减少内存使用量,并在两次测试之间将设备恢复到干净状态
- 缓存测试结果,并且仅重新运行可能提供不同结果的测试
- 为在本地和远程测试运行之间运行测试提供一致的环境
创建虚拟 Gradle 管理的设备
您可以在模块级构建文件中指定 Gradle 用于测试应用的虚拟设备。以下代码示例将运行 API 级别 30 的 Pixel 2 创建为 Gradle 管理的设备。
Kotlin
android { testOptions { managedDevices { localDevices { create("pixel2api30") { // Use device profiles you typically see in Android Studio. device = "Pixel 2" // Use only API levels 27 and higher. apiLevel = 30 // To include Google services, use "google". systemImageSource = "aosp" } } } } }
Groovy
android { testOptions { managedDevices { localDevices { pixel2api30 { // Use device profiles you typically see in Android Studio. device = "Pixel 2" // Use only API levels 27 and higher. apiLevel = 30 // To include Google services, use "google". systemImageSource = "aosp" } } } } }
定义设备组
为了帮助您针对多种设备配置(例如不同的 API 级别和外形规格)扩展测试,您可以定义多个 Gradle 管理的设备,并将它们添加到命名组中。Gradle 随后可以并行地在组中的所有设备上执行您的测试。
以下示例显示了添加到名为 phoneAndTablet
的设备组中的两个设备。
Kotlin
testOptions { managedDevices { localDevices { create("pixel2api29") { ... } create("nexus9api30") { ... } } groups { create("phoneAndTablet") { targetDevices.add(devices["pixel2api29"]) targetDevices.add(devices["nexus9api30"]) } } } }
Groovy
testOptions { managedDevices { localDevices { pixel2api29 { ... } nexus9api30 { ... } } groups { phoneAndTablet { targetDevices.add(devices.pixel2api29) targetDevices.add(devices.nexus9api30) } } } }
运行测试
如需使用您配置的 Gradle 管理的设备运行测试,请使用以下命令。device-name
是您在 Gradle 构建脚本中配置的设备名称(例如 pixel2api30
),BuildVariant
是您要测试的应用的构建变体。
在 Windows 上
gradlew device-nameBuildVariantAndroidTest
在 Linux 或 macOS 上
./gradlew device-nameBuildVariantAndroidTest
如需在一组 Gradle 管理的设备上运行测试,请使用以下命令。
在 Windows 上
gradlew group-nameGroupBuildVariantAndroidTest
在 Linux 或 macOS 上
./gradlew group-nameGroupBuildVariantAndroidTest
测试输出包含指向 HTML 文件的路径,该文件具有测试报告。您还可以通过在 IDE 中点击 Run > Test History 将测试结果导入 Android Studio 进行进一步分析。
启用测试分片
Gradle 管理的设备支持测试分片,可让您将测试套件拆分到多个相同的虚拟设备实例(称为 shard)中,这些实例并行运行。使用测试分片有助于缩短整体测试执行时间,但会增加计算资源成本。
如需设置给定测试运行中要使用的分片数量,请在您的 gradle.properties
文件中设置以下内容
android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>
使用此选项运行测试时,Gradle 管理的设备会为测试运行中的每个设备配置文件预配您指定的分片数量。因此,例如,如果您将测试部署到包含三个设备的设备组,并将 numManagedDeviceShards
设置为二,Gradle 管理的设备将为您的测试运行总共预配六个虚拟设备。
测试完成后,Gradle 会为测试运行中使用的每个分片将测试结果输出到 .proto
文件中。
使用自动化测试设备
Gradle 管理的设备支持一种名为自动化测试设备 (ATD) 的模拟器设备,该设备经过优化,可在运行插桩测试时减少 CPU 和内存资源。ATD 通过以下几种方式提高运行时性能
- 移除通常对测试应用无用的预装应用
- 停用通常对测试应用无用的某些后台服务
- 停用硬件渲染
开始之前,请确保将 Android 模拟器更新到最新版本。然后,在模块级构建文件中定义 Gradle 管理的设备时,指定一个“-atd”镜像,如下所示
Kotlin
android { testOptions { managedDevices { localDevices { create("pixel2api30") { // Use device profiles you typically see in Android Studio. device = "Pixel 2" // ATDs currently support only API level 30. apiLevel = 30 // You can also specify "google-atd" if you require Google Play Services. systemImageSource = "aosp-atd" } } } } }
Groovy
android { testOptions { managedDevices { localDevices { pixel2api30 { // Use device profiles you typically see in Android Studio. device = "Pixel 2" // ATDs currently support only API level 30. apiLevel = 30 // You can also specify "google-atd" if you require Google Play Services. systemImageSource = "aosp-atd" } } } } }
您还可以像其他 Gradle 管理的设备一样创建设备组。为了进一步提升性能,您还可以将 ATD 与测试分片结合使用,以减少测试套件的总测试执行时间。
ATD 镜像中移除了哪些内容?
除了以无头模式运行外,ATD 还通过移除或停用通常不需要测试应用代码的应用和服务来优化性能。下表概述了我们在 ATD 镜像中移除或停用的组件,并说明了它们可能无用的原因。
ATD 镜像中移除的内容 | 在运行自动化测试时您可能不需要此功能的原因 |
---|---|
Google 产品应用
|
您的自动化测试应侧重于您自己的应用逻辑,同时假定其他应用或平台将正常运行。 使用 Espresso-Intents,您可以匹配和验证传出 intent,甚至提供存根响应来代替实际的 intent 响应。 |
设置应用和服务
|
这些应用提供图形用户界面,供最终用户更改平台设置、设置其设备或管理设备存储。这通常超出应用级自动化测试的范围。
|
SystemUI | 您的自动化测试应侧重于您自己的应用逻辑,同时假定其他应用或平台将正常运行。 |
AOSP 应用和服务
|
这些应用和服务通常超出您应用代码的自动化测试范围。 |
使用 Firebase Test Lab 设备
使用 Gradle 管理的设备时,您可以在 Firebase Test Lab 设备上大规模运行自动化插桩测试。Test Lab 允许您在各种 Android 设备(包括实体设备和虚拟设备)上同时运行测试。这些测试在远程 Google 数据中心运行。在 Gradle 管理的设备的支持下,构建系统可以根据您的配置全面管理针对这些 Test Lab 设备运行的测试。
开始使用
以下步骤介绍了如何开始将 Firebase Test Lab 设备与 Gradle 管理的设备结合使用。请注意,这些步骤使用 gcloud CLI 提供用户凭据,这可能不适用于所有开发环境。有关如何根据您的需求使用哪种身份验证过程的更多信息,请参阅 应用默认凭据的工作原理。
如需创建 Firebase 项目,请前往 Firebase 控制台。点击 Add project,然后按照屏幕上的提示创建项目。请记住您的项目 ID。
如需安装 Google Cloud CLI,请按照 安装 gcloud CLI 中的步骤操作。
配置本地环境。
在 gcloud 中链接到您的 Firebase 项目
gcloud config set project FIREBASE_PROJECT_ID
授权使用您的用户凭据访问 API。我们建议通过在模块级构建脚本中使用 DSL 将服务帐号 JSON 文件传递给 Gradle 来进行授权
Kotlin
firebaseTestLab { ... serviceAccountCredentials.set(file(SERVICE_ACCOUNT_JSON_FILE)) }
Groovy
firebaseTestLab { ... serviceAccountCredentials = file(SERVICE_ACCOUNT_JSON_FILE) }
或者,您可以使用以下终端命令手动授权
gcloud auth application-default login
可选:将您的 Firebase 项目添加为配额项目。仅当您超出 Test Lab 的免费配额时才需要此步骤。
gcloud auth application-default set-quota-project FIREBASE_PROJECT_ID
启用所需的 API。
在 Google Developers Console API 库页面中,在控制台顶部的搜索框中输入这些 API 名称,然后点击每个 API 概览页面上的 Enable API,从而启用 Cloud Testing API 和 Cloud Tool Results API。
配置您的 Android 项目。
在顶级构建脚本中添加 Firebase Test Lab 插件
Kotlin
plugins { ... id("com.google.firebase.testlab") version "0.0.1-alpha05" apply false }
Groovy
plugins { ... id 'com.google.firebase.testlab' version '0.0.1-alpha05' apply false }
在
gradle.properties
文件中启用自定义设备类型android.experimental.testOptions.managedDevices.customDevice=true
在模块级构建脚本中添加 Firebase Test Lab 插件
Kotlin
plugins { ... id "com.google.firebase.testlab" }
Groovy
plugins { ... id 'com.google.firebase.testlab' }
指定 Test Lab 设备
您可以在模块级构建脚本中指定 Gradle 用于测试应用的 Firebase Test Lab 设备。以下代码示例将运行 API 级别 30 的 Pixel 3 创建为名为 ftlDevice
的 Gradle 管理的 Test Lab 设备。当您将 com.google.firebase.testlab
插件应用于模块时,firebaseTestLab {}
块可用。
Kotlin
firebaseTestLab { managedDevices { create("ftlDevice") { device = "Pixel3" apiLevel = 30 } } ... }
Groovy
firebaseTestLab { managedDevices { ftlDevice { device = "Pixel3" apiLevel = 30 } } ... }
如需定义包含 Firebase Test Lab 设备的 Gradle 管理设备组,请参阅定义设备组。
如需运行测试,请使用运行其他 Gradle 管理设备的相同命令。请注意,Gradle 不会并行运行测试,也不支持 Test Lab 设备的任何其他 Google Cloud CLI 配置。
通过智能分片优化测试运行
在 Gradle 管理的 Test Lab 设备上进行测试支持智能分片。智能分片会自动将测试分发到各个分片,使每个分片运行大致相同的时间,从而减少手动分配工作并缩短总体测试运行时间。智能分片使用您的测试历史记录(或有关您的测试之前运行了多长时间的信息)以最佳方式分发测试。请注意,您需要 Firebase Test Lab 的 Gradle 插件版本 0.0.1-alpha05 才能使用智能分片。
如需启用智能分片,请指定每个分片中的测试应花费的时间量。您应将目标分片时间持续时间设置为比 timeoutMinutes
至少少五分钟,以避免分片在测试完成之前被取消的情况。
firebaseTestLab { ... testOptions { targetedShardDurationMinutes = 2 } }
如需了解更多信息,请阅读有关 Firebase Test Lab 设备 DSL 选项的内容。
Test Lab 设备的更新版 DSL
您可以配置更多 DSL 选项,以帮助自定义测试运行或从您可能已使用的其他解决方案迁移。请参阅以下代码段中描述的一些选项。
firebaseTestLab { ... /** * A path to a JSON file that contains service account credentials to access to * a Firebase Test Lab project. */ serviceAccountCredentials.set(file("your_service_account_credentials.json")) testOptions { fixture { /** * Whether to grant permissions on the device before tests begin. * Available options are "all" or "none". * * Default value is "all". */ grantedPermissions = "all" /** * Map of files to push to the device before starting the test. * * The key is the location on the device. * The value is the location of the file, either local or in Google Cloud. */ extraDeviceFiles["/sdcard/dir1/file1.txt"] = "local/file.txt" extraDeviceFiles["/sdcard/dir2/file2.txt"] = "gs://bucket/file.jpg" /** * The name of the network traffic profile. * * Specifies network conditions to emulate when running tests. * * Default value is empty. */ networkProfile = "LTE" } execution { /** * The maximum time to run the test execution before cancellation, * measured in minutes. Does not include the setup or teardown of device, * and is handled server-side. * * The maximum possible testing time is 45 minutes on physical devices * and 60 minutes on virtual devices. * * Defaults to 15 minutes. */ timeoutMinutes = 30 /** * Number of times the test should be rerun if tests fail. * The number of times a test execution should be retried if one * or more of its test cases fail. * * The max number of times is 10. * * The default number of times is 0. */ maxTestReruns = 2 /** * Ensures only a single attempt is made for each execution if * an infrastructure issue occurs. This doesn't affect `maxTestReruns`. * Normally, two or more attempts are made by Firebase Test Lab if a * potential infrastructure issue is detected. This is best enabled for * latency sensitive workloads. The number of execution failures might be * significantly greater with `failFast` enabled. * * Defaults to false. */ failFast = false /** * The number of shards to split the tests across. * * Default to 0 for no sharding. */ numUniformShards = 20 } /** * For smart sharding, the target length of time each shard should takes in * minutes. Maxes out at 50 shards for physical devices and 100 shards for * virtual devices. * * Only one of numUniformShards or targetedShardDurationMinutes can be set. * * Defaults to 0 for no smart sharding. */ targetedShardDurationMinutes = 15 } results { /** * The name of the Google storage bucket to store the test results in. * * If left unspecified, the default bucket is used. * * Please refer to Firebase Test Lab permissions for required permissions * for using the bucket. */ cloudStorageBucket = "bucketLocationName" /** * Name of test results for the Firebase console history list. * All tests results with the same history name are grouped * together in the Firebase console in a time-ordered test history list. * * Defaults to the application label in the APK manifest. */ resultsHistoryName = "application-history" /** * List of paths to copy from the test device's storage to the test * results folder. These must be absolute paths under /sdcard or * /data/local/tmp. */ directoriesToPull.addAll( "/sdcard/path/to/something" ) /** * Whether to enable video recording during the test. * * Disabled by default. */ recordVideo = false /** * Whether to enable performance metrics. If enabled, monitors and records * performance metrics such as CPU, memory, and network usage. * * Defaults to false. */ performanceMetrics = true } }