使用 Gradle 管理的设备扩展测试

Gradle 管理的设备可以提高自动化插桩测试的一致性、性能和可靠性。此功能适用于 API 级别 27 及更高级别,可用于在项目的 Gradle 文件中配置虚拟测试设备。在执行自动化测试时,构建系统会使用这些配置来完全代管(即创建、部署和拆解)这些设备。

借助这项功能,Gradle 不仅对正在运行的测试了如指掌,而且设备的生命周期也尽在把握,因此可从以下几个方面提高测试体验的质量:

  • 处理设备相关问题,以确保顺利执行测试
  • 利用模拟器快照缩短设备启动时间,减少内存用量,并在每次测试完毕后都让设备恢复到干净状态,方便进行下一次测试
  • 缓存测试结果,并且仅重新运行可能会提供不同结果的测试
  • 为本地测试和远程测试提供一致的测试运行环境

此外,Gradle 管理的设备还引入了一种称为自动化测试设备 (ATD) 的新型模拟器设备,该设备经过优化,可在运行插桩测试时提高性能。结合对测试分片的支持,您可以尝试在多个 ATD 实例间拆分测试套件,以缩短总测试执行时间。

创建 Gradle 管理的设备

您可以在模块级 build.gradle 文件中指定希望 Gradle 用于测试应用的虚拟设备。以下代码示例将创建一个搭载 API 级别 30 的 Pixel 2 作为 Gradle 管理的设备。

Groovy

android {
  testOptions {
    managedDevices {
      devices {
        pixel2api30 (com.android.build.api.dsl.ManagedVirtualDevice) {
          // 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"
        }
      }
    }
  }
}

Kotlin

android {
  testOptions {
    managedDevices {
      devices {
        maybeCreate<com.android.build.api.dsl.ManagedVirtualDevice>("pixel2api30").apply {
          // 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"
        }
      }
    }
  }
}

如需使用您配置的由 Gradle 管理的设备运行测试,请使用以下命令。device-name 是您在 Gradle build 脚本中配置的设备名称(例如 pixel2api30),BuildVariant 是要测试的应用 build 变体。

gradlew device-nameBuildVariantAndroidTest

定义设备组

为了帮助您跨多个设备配置(例如不同的 API 级别和外形规格)扩展测试,您可以定义多个由 Gradle 管理的设备并将其添加到已命名的组。然后,Gradle 可在组中的所有设备上并行执行测试。

下面的示例显示了如何将两个受管设备添加到名为 phoneAndTablet 的设备组。

Groovy

testOptions {
  managedDevices {
    devices {
      pixel2api29 (com.android.build.api.dsl.ManagedVirtualDevice) { ... }
      nexus9api30 (com.android.build.api.dsl.ManagedVirtualDevice) { ... }
    }
    groups {
      phoneAndTablet {
        targetDevices.add(devices.pixel2api29)
        targetDevices.add(devices.nexus9api30)
      }
    }
  }
}

Kotlin

testOptions {
  managedDevices {
    devices {
      maybeCreate<com.android.build.api.dsl.ManagedVirtualDevice>("pixel2api29").apply { ... }
      maybeCreate<com.android.build.api.dsl.ManagedVirtualDevice>("nexus9api30").apply { ... }
    }
    groups {
      maybeCreate("phoneAndTablet").apply {
        targetDevices.add(devices["pixel2api29"])
        targetDevices.add(devices["nexus9api30"])
      }
    }
  }
}

如需使用 Gradle 管理的设备组运行测试,请使用以下命令:

gradlew group-nameGroupBuildVariantAndroidTest

使用自动化测试设备运行测试

Gradle 管理的设备支持一种称为自动化测试设备 (ATD) 的新型模拟器设备,该设备经过优化,可以减少运行插桩测试时所需的 CPU 和内存资源。ATD 通过以下几种方式提高运行时性能:

  • 移除通常对应用测试无用的预安装应用
  • 停用通常对应用测试无用的某些后台服务
  • 停用硬件渲染

首先,请务必将 Android 模拟器更新到最新可用版本。然后,在 build.gradle 中定义 Gradle 管理的设备时指定“-atd”映像,如下所示:

Groovy

android {
  testOptions {
    managedDevices {
      devices {
        pixel2api30 (com.android.build.api.dsl.ManagedVirtualDevice) {
          // 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"
        }
      }
    }
  }
}

Kotlin

android {
  testOptions {
    managedDevices {
      devices {
        maybeCreate<com.android.build.api.dsl.ManagedVirtualDevice>("pixel2api30").apply {
          // 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 产品应用:
  • 邮件
  • 地图
  • Chrome
  • 信息
  • Play 商店等
自动化测试应当侧重于您自己的应用的逻辑,同时假定其他应用或平台能够正常运行。

借助 Espresso-Intents,您可以匹配和验证您的传出 intent,甚至可以提供桩响应来代替实际的 intent 响应。

设置方面的应用和服务:
  • CarrierConfig
  • EmergencyInfo
  • OneTimeInitializer
  • PhotoTable(屏保)
  • 配置
  • “设置”应用
  • StorageManager
  • 电话 APN 配置
  • WallpaperCropper
  • WallpaperPicker
这些应用为最终用户提供用于更改平台设置、设置设备或管理设备存储空间所需的 GUI。这通常不在应用级自动化测试的范围之内。


注意:ATD 映像中仍然提供了设置提供程序

SystemUI 自动化测试应当侧重于您自己的应用的逻辑,同时假定其他应用或平台能够正常运行。
AOSP 应用和服务:
  • Browser2
  • 日历
  • Camera2
  • 通讯录
  • 拨号器
  • 桌面时钟
  • Gallery2
  • LatinIME
  • Launcher3QuickStep
  • 音乐
  • QuickSearchBox
  • SettingsIntelligence
这些应用和服务通常不在应用代码的自动化测试范围之内。

启用测试分片

Gradle 管理的设备支持测试分片,可以让您在多个并行运行的相同虚拟设备实例(称为“分片”)间拆分测试套件。使用测试分片有助于缩短总测试执行时间,但代价是会消耗额外的计算资源。

如需设置要在指定测试运行中使用的分片数,请在 gradle.properties 文件中进行以下设置:

android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>

使用此选项运行测试时,Gradle 管理的设备会为测试运行中的每个设备配置文件配置您指定的分片数。例如,如果您将测试部署到包含 3 个设备的设备组,并将 numManagedDeviceShards 设为 2,那么 Gradle 管理的设备将为测试运行配置共计 6 个虚拟设备。

测试完成后,对于测试运行中使用的每个分片,Gradle 会将相应测试结果分别输出到一个 .proto 文件中。