高级测试设置

在 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 视图中未处于活跃状态。

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

配置插桩测试清单设置

插桩测试内置于拥有专属 AndroidManifest.xml 文件的单独 APK中。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
    }
}

Each product flavor you configure can override properties in the defaultConfig {} block. To learn more, go to Configure product flavors.

The properties in the snippet are:

Setting Description
testApplicationId Specifies the application ID for the test APK.
testInstrumentationRunner Specifies the fully qualified class name of the test instrumentation runner.
testHandleProfiling If set to true, enables the instrumentation class to start and stop profiling.
If set to false, profiling occurs the entire time the instrumentation class is running.
testFunctionalTest If set to true, indicates that the Android system should run the instrumentation class as a functional test.
The default value is false.

Change the test build type

By default, all instrumentation tests run against the debug build type. You can change this to another build type by using the testBuildType property in your module-level build.gradle file. For example, if you want to run your tests against your staging build type, edit the file as shown in the following snippet:

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 属性来限制要测试哪些变体。这样一来,测试模块也不必针对自身配置这些变体。