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 中点击运行 > 测试历史记录将测试结果导入 Android Studio 以进行进一步分析。
启用测试分片
Gradle 管理的设备支持测试分片,它允许您将测试套件拆分到多个相同的虚拟设备实例(称为分片)中,这些实例并行运行。使用测试分片可以帮助减少整体测试执行时间,但代价是需要额外的计算资源。
要设置在给定测试运行中要使用的分片数,请在您的 gradle.properties
文件中设置以下内容
android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>
使用此选项运行测试时,Gradle 管理的设备会为测试运行中的每个设备配置文件预配您指定的分片数。例如,如果您将测试部署到包含三个设备的设备组并将 numManagedDeviceShards
设置为 2,则 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,您可以匹配和验证您的传出意图,甚至可以提供存根响应来代替实际的意图响应。 |
设置应用和服务
|
这些应用为最终用户提供了一个 GUI,用于更改平台设置、设置设备或管理设备存储。这通常超出了应用级自动化测试的范围。
|
SystemUI | 您的自动化测试应重点关注您自己的应用逻辑,同时假设其他应用或平台将正常运行。 |
AOSP 应用和服务
|
这些应用和服务通常超出了应用代码自动化测试的范围。 |
使用 Firebase Test Lab 设备
在使用 Gradle 管理的设备时,您可以在 Firebase Test Lab 设备上大规模运行自动化仪器测试。Test Lab 允许您同时在各种 Android 设备(包括物理设备和虚拟设备)上运行测试。这些测试在远程 Google 数据中心运行。在 Gradle 管理的设备的支持下,构建系统可以根据您的配置完全管理针对这些 Test Lab 设备运行测试。
开始使用
以下步骤介绍了如何开始使用 Gradle 管理的设备与 Firebase Test Lab 设备。请注意,这些步骤使用 gcloud CLI 提供用户凭据,这可能不适用于所有开发环境。有关适合您需求的认证流程的更多信息,请参阅 应用默认凭据的工作原理。
要创建 Firebase 项目,请访问 Firebase 控制台。点击添加项目,然后按照屏幕上的提示创建项目。请记住您的项目 ID。
要安装 Google Cloud CLI,请按照 安装 gcloud CLI 中的步骤操作。
配置您的本地环境。
链接到 gcloud 中的 Firebase 项目
gcloud config set project FIREBASE_PROJECT_ID
授权使用您的用户凭据进行 API 访问。我们建议通过将 服务帐号 JSON 文件 传递到 Gradle 来授权,方法是使用模块级构建脚本中的 DSL。
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 库页面 中,启用 Cloud Testing API 和 Cloud Tool Results API,方法是在控制台顶部的搜索框中输入这些 API 名称,然后点击每个 API 的概览页面上的启用 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 in Flank/Fladle. */ 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 } }