高级测试设置

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

在 Android Studio 中进行测试从命令行进行测试页面介绍了如何设置并运行基本测试配置。但是,如果您的应用及其测试要求越来越高级,您可能需要进一步调整测试配置。例如,如果您想执行以下操作,可能需要用到高级测试设置:

  • 仅针对特定 build 变体运行插桩测试,或替换其清单设置。
  • 更改用于运行测试的 build 类型,或配置其 Gradle 选项。
  • 将插桩测试提取到各自的测试模块中。
  • 在持续集成设置过程中,执行更高级的测试。

本页面将介绍当默认设置无法满足您的需求时配置测试的各种方法。

为 build 变体创建插桩测试

如果您的项目包含的 build 变体具有专属的源代码集,您可能希望包含与这些源代码集对应的插桩测试。这样有助于保持测试代码的条理性,并可以仅运行适用于给定 build 变体的测试。

如需将插桩测试关联到 build 变体,请将它们放在其自身的源代码集中(位于 src/androidTestVariantName)。

src/androidTest/ 源代码集中的插桩测试适用于所有 build 变体。为应用的“MyFlavor”变体构建测试 APK 时,Gradle 会将 src/androidTest/src/androidTestMyFlavor/ 这两个源代码集合并。

如需在 Android Studio 中为 build 变体添加测试源代码集,请按以下步骤操作:

  1. Project 窗口中,点击菜单并选择 Project 视图。
  2. 在相应的模块文件夹内,右键点击 src 文件夹,然后依次点击 New > Directory
  3. 对于目录名称,请输入“androidTestVariantName”。例如,如果您有一个名为“MyFlavor”的 build 变体,则可以使用目录名称 androidTestMyFlavor
  4. 点击 OK
  5. 右键点击新目录,然后依次选择 New > Directory
  6. 输入“java”作为目录名,然后点击 OK

现在您就可以按照上述添加新测试的步骤向这个新源代码集添加测试了。当您看到 Choose Destination Directory 对话框时,请选择新的变体测试源代码集。

下表显示了一个示例,展示插桩测试文件如何位于与应用代码源代码集对应的源代码集中。

表 1. 应用源代码和相应的插桩测试文件

应用类的路径 对应插桩测试类的路径
src/main/java/Example.java src/androidTest/java/AndroidExampleTest.java
src/myFlavor/java/Example.java src/androidTestMyFlavor/java/AndroidExampleTest.java

Gradle 构建系统会合并和替换来自不同测试源代码集的文件,就像它对应用源代码集的处理方法一样。在本示例中,androidTestMyFlavor 源代码集内的 AndroidExampleTest.java 文件会替换 androidTest 源代码集内的版本。原因在于产品变种源代码集的优先级高于主源代码集。

当您在 build 变体选择器中选择不同的变种时,Android 视图中会显示相应的 androidTest 文件夹,以显示所使用的文件夹:

已选择 MyFlavor 变体,且 Android 视图中显示了 androidTestMyFlavor 文件夹
图 1. 已选择 MyFlavor 个变体;androidTestMyFlavor 文件夹会显示在 Android 视图中。

如果选择其他变体,系统不会显示 androidTestMyFlavor 文件夹:

已选择 OtherFlavor 变体,且“Android”视图中未显示 androidTestMyFlavor 文件夹
图 2. 已选择 OtherFlavor 个变体;androidTestMyFlavor 文件夹不会显示在 Android 视图中。

如果您使用的是 Project 视图,这看起来略有不同,但适用的原则是一样的:

已选择 MyFlavor 变体,而且 androidTestMyFlavor 文件夹在“Project”视图中处于活跃状态
图 3. 已选择 MyFlavor 个变体;androidTestMyFlavor 文件夹在 Project 视图中处于活跃状态。

选择其他变体时,androidTestMyFlavor 文件夹仍然可见,但不会显示为活跃状态:

已选择 OtherFlavor 变体,而且 androidTestMyFlavor 文件夹在“Project”视图中未处于活跃状态
图 4. 已选择 OtherFlavor 个变体;androidTestMyFlavor 文件夹在 Project 视图中未处于活跃状态。

如需详细了解如何合并源代码集,请参阅源代码集

配置插桩测试清单设置

插桩测试内置于单独的 APK 中,拥有自己的 AndroidManifest.xml 文件。Gradle 在构建测试 APK 时,会自动生成 AndroidManifest.xml<instrumentation> 文件,并为其配置 节点。Gradle 为您配置此节点的原因之一是,确保 targetPackage 属性指定了受测应用的正确软件包名称。

如需更改此节点的其他设置,请在测试源代码集中再创建一个清单文件,或配置模块级 build.gradle 文件,如以下代码示例所示。您可以在 BaseFlavor API 参考文档中找到完整的选项列表。

Groovy

android {
    ...
    defaultConfig {
        ...
        testApplicationId "com.example.test"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testHandleProfiling true
        testFunctionalTest true
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        testApplicationId = "com.example.test"
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        testHandleProfiling = true
        testFunctionalTest = true
    }
}

您配置的每个产品变种都可以替换 defaultConfig {} 代码块中的属性。如需了解详情,请参阅配置产品变种

该代码段中的属性为:

设置 说明
testApplicationId 指定测试 APK 的应用 ID
testInstrumentationRunner 指定插桩测试运行程序的完全限定类名。
testHandleProfiling 如果设置为 true,则允许插桩类开始和停止分析。
如果设置为 false,则在整个插桩类运行期间进行分析。
testFunctionalTest 如果设置为 true,则表示 Android 系统应将插桩类作为功能测试运行。
默认值为 false

更改测试 build 类型

默认情况下,所有插桩测试都会针对 debug build 类型运行。 您可以使用模块级 build.gradle 文件中的 testBuildType 属性将其更改为针对其他 build 类型运行。例如,如果您想针对 staging build 类型运行测试,请按下面这段代码中所示对该文件进行编辑。

Groovy

android {
    ...
    testBuildType "staging"
}

Kotlin

android {
    ...
    testBuildType = "staging"
}

配置 Gradle 测试选项

借助 Android Gradle 插件,您可以为所有或部分测试指定特定选项。在模块级 build.gradle 文件中,可以使用 testOptions 代码块指定相关选项来更改 Gradle 运行所有测试的方式。

Groovy

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        reportDir "$rootDir/test-reports"
        resultsDir "$rootDir/test-results"
    }
}

Kotlin

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        reportDir "$rootDir/test-reports"
        resultsDir = "$rootDir/test-results"
    }
}

reportDir 属性可更改 Gradle 保存测试报告的目录。默认情况下,Gradle 会将测试报告保存在 path_to_your_project/module_name /build/outputs/reports/ 目录中。$rootDir 会设置相对于当前项目根目录的路径。

resultsDir 属性可更改 Gradle 保存测试结果的目录。默认情况下,Gradle 会将测试结果保存在 path_to_your_project/module_name /build/outputs/test-results/ 目录中。$rootDir 会设置相对于当前项目根目录的路径。

如需仅为本地单元测试指定选项,请配置 testOptions 中的 unitTests 代码块。

Groovy

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            returnDefaultValues true

            all {
                jvmArgs '-XX:MaxPermSize=256m'

                if (it.name == 'testDebugUnitTest') {
                    systemProperty 'debug', 'true'
                }
                ...
            }
        }
    }
}

Kotlin

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            returnDefaultValues = true

            all {
                jvmArgs = listOf("-XX:MaxPermSize=256m")

                 if (it.name == "testDebugUnitTest") {
                    systemProperty = mapOf("debug" to "true")
                }
                ...
            }
        }
    }
}

默认情况下,只要您测试的代码尝试访问 Android 平台 API,本地单元测试就会抛出异常,除非您自行或通过测试框架(如 Mockito)模拟 Android 依赖项。不过,您可以启用 returnDefaultValues 属性,以便测试的代码在访问平台 API 时返回 null 或 0,而不是抛出异常。

all 代码块可封装用于控制 Gradle 如何执行本地单元测试的选项。如需查看您可以指定的所有选项的列表,请参阅 Gradle 的参考文档

jvmArgs 属性用于为测试 JVM 设置 JVM 参数。

您还可以检查任务名称,以便仅将选项应用于您指定的测试。在示例代码段中,debug 属性设置为 true,但仅用于 testDebugUnitTest 任务。

对插桩测试使用单独的测试模块

如果您希望某个模块专用于插桩测试并将代码的其余部分与测试隔离,您可以创建一个单独的测试模块并配置其 build,创建和配置方式与库模块类似。

如需创建测试模块,请按以下步骤操作:

  1. 创建一个库模块
  2. 在模块级 build.gradle 文件中,应用 com.android.test 插件(而非 com.android.library)。
  3. 点击 Sync Project 图标

创建测试模块后,您可以在主源代码集或变体源代码集(例如 src/main/javasrc/variant/java)内添加您的测试代码。如果您的应用模块定义了多个产品变种,您可以在测试模块中重新创建这些变种,并且测试模块会使用变体感知依赖项管理功能尝试测试目标模块中的匹配变种。

默认情况下,测试模块仅包含并测试 debug 变体。不过,您可以创建新的 build 类型,使其与测试的应用项目匹配。如需让测试模块对其他 build 类型(而非调试 build 类型)进行测试,请使用 VariantFilter 停用测试项目中的 debug 变体,如下所示:

Groovy

android {
    variantFilter { variant ->
        if (variant.buildType.name.equals('debug')) {
            variant.setIgnore(true);
        }
    }
}

Kotlin

android {
    variantFilter {
        if (buildType.name == "debug") {
            ignore = true
        }
    }
}

如果您希望测试模块仅对应用的某些变种或 build 类型进行测试,则可以使用 matchingFallbacks 属性来限制要测试哪些变体。这也使得测试模块无需针对自身配置这些变体。