Android Gradle 插件 (AGP) 可以使用设备端覆盖率代理为插桩测试创建代码覆盖率报告。默认情况下,AGP 在构建应用时会使用 JaCoCo 对应用的类进行插桩,这意味着它会添加代码来记录测试运行了应用的哪些部分。借助设备端覆盖率代理,AGP 在构建应用时不会添加这些额外代码,而代理会在测试运行期间在测试设备上对应用的类进行插桩。本页介绍了如何启用设备端代码覆盖率并生成报告。
与构建时代码覆盖率相比,设备端代码覆盖率具有以下优势:
- 更快的构建速度:AGP 不会在应用的类及其依赖项上运行 JaCoCo 插桩步骤,这可以将构建时间缩短 10-20%。
- 更小的调试 APK:AGP 不会向应用的类添加覆盖率跟踪代码,这可使调试 APK 的大小缩减 20-25%。
- 报告中不包含未使用的生成类:测试未使用的生成类不会降低覆盖率。
实际的构建时间和 APK 大小缩减幅度取决于您的项目。
前提条件
如需使用设备端代码覆盖率,请确保您的项目和测试设备满足以下要求:
- AGP 9.6.0-alpha01 或更高版本。
- 搭载 Android 9(API 级别 28)或更高版本的设备或模拟器。
- 所测试变体的可调试 build 类型,例如默认的
debugbuild 类型。该代理只能附加到可调试的应用。 - 使用
AndroidJUnitRunner或扩展它的自定义测试运行程序运行的插桩测试。
启用设备端代码覆盖率
设备端代码覆盖率使用与 build 时代码覆盖率相同的 enableAndroidTestCoverage 属性。在模块级 build 文件中,为您要获取覆盖率报告的每个变体将 enableAndroidTestCoverage 设置为 true:
Kotlin
android {
// ...
buildTypes {
debug {
// Enable coverage for instrumentation tests
enableAndroidTestCoverage = true
}
}
}
Groovy
android {
// ...
buildTypes {
debug {
// Enable coverage for instrumentation tests
enableAndroidTestCoverage true
}
}
}
然后,在项目的 gradle.properties 文件中启用设备端覆盖率代理和报告汇总功能:
android.experimental.androidTest.coverage.useOnDeviceAgent=true
android.experimental.reportAggregationSupport=true
设备端代码覆盖率会使用与统一代码覆盖率报告相同的渲染程序生成其 HTML 报告,因此它需要这两个属性。
生成设备端代码覆盖率报告
如需运行插桩测试并生成覆盖率报告,请连接设备或启动模拟器,然后运行以下任务:
| 覆盖范围 | 命令 | 报告位置 |
|---|---|---|
| 1 个变体 | ./gradlew :module-name:createVariantNameAndroidTestCoverageReport |
path-to-your-project/module-name/build/reports/coverage/androidTest/variant/connected/index.html |
与构建时代码覆盖率的差异
对于相同的测试,设备端和构建时覆盖率报告可能会显示不同的结果。在比较这两个报告或将覆盖率阈值从一个报告移至另一个报告时,请注意以下差异:
| 领域 | 构建时代码覆盖率 | 设备端代码覆盖率 |
|---|---|---|
| 何时对类进行插桩 | 当 AGP 使用 JaCoCo 构建应用时 | 在测试运行期间,使用覆盖率代理在测试设备上运行 |
| 报告中的课程 | 模块中的所有类 | 仅包含模块命名空间中在测试运行期间加载的类,因此覆盖率百分比可能会更高 |
| 指令计数 | Java 字节码指令 | DEX 字节码指令 |
| 分支计数 | Java 字节码中的分支 | DEX 字节码中的分支。D8 可以将条件编译到不同的分支中,并且每个工具都会省略不同的编译器生成的分支,因此计数可能会有所不同。 |
| 计数器 | 指令、分支、行、复杂度、方法和类 | 指令、分支、行、方法和类。尚不支持复杂性计数器。 |
| 测试设备 | 您的应用支持的所有 API 级别 | Android 9(API 级别 28)及更高版本 |
| 原始覆盖率数据 | .ec 个文件 |
coverage_metadata.pb 和 coverage_hits.pb 文件 |
如需切换回 build 时代码覆盖率,请设置 android.experimental.androidTest.coverage.useOnDeviceAgent=false 或移除该属性。您无需更改 build 文件或运行的任务。
已知问题
设备端代码覆盖率存在以下已知问题:
- 未加载的类:在测试运行期间从未加载的类不会显示在报告中。构建时代码覆盖率报告会将其列为 0% 覆盖率。
- 汇总报告:如果您的项目还从主机测试(例如单元测试)中收集覆盖率,则
testAllSuites和testAllSuitesWithDependencies任务创建的汇总覆盖率报告会将这些测试中的 Java 字节码计数与代理中的 DEX 字节码计数结合起来。由于两者之间存在差异,汇总的指令和分支数量可能与构建时代码覆盖率报告中的数量不同。
通过问题跟踪器报告任何其他反馈和问题。