Android 单元测试

1.概念

测试应用 通过持续对应用运行测试,您可以在公开发布应用之前验证其正确性、功能行为和易用性

  • 快速获得故障反馈

  • 在开发周期中尽早进行故障检测

  • 更安全的代码重构,让您可以优化代码而不必担心回归。

  • 稳定的开发速度,帮助您最大限度地减轻技术负担

2.测试基础知识

2.1 配置测试环境

Android Studio 中的典型项目包含两个用于放置测试的目录

  • androidTest 目录应包含在真实或虚拟设备上运行的测试。此类测试包括集成测试、端到端测试,以及仅靠 JVM 无法完成应用功能验证的其他测试。
  • test 目录应包含在本地计算机上运行的测试,如单元测试。

2.2 编写测试

1 编写小型测试

小型测试应该是高度集中的单元测试,能够详尽地验证应用中每个类的功能和约定。

在特定类中添加和更改方法时,请针对它们创建和运行单元测试。如果这些测试依赖于 Android 框架,请使用与设备无关的统一 API,如 androidx.test API。这种一致性可让您在本地运行测试,而无需使用物理设备或模拟器。

如果您的测试依赖于资源,请在 应用的 build.gradle 文件中启用 includeAndroidResources 选项。然后,您的单元测试可以访问编译版本的资源,从而使测试更快速且更准确地运行。

app/build.gradle

注意:默认情况下,Android Studio 3.4 及更高版本提供编译版本的资源

android {
// ...

    testOptions {
        unitTests {
        includeAndroidResources = true
    }
}

尽可能使用 AndroidX Test API,以便您的单元测试可以在设备或模拟器上运行。

对于始终在由 JVM 驱动的开发计算机上运行的测试,您可以使用 Robolectric。

Robolectric 会模拟 Android 4.1(API 级别 16)或更高版本的运行时环境,并提供由社区维护的虚假对象(称为“影子”)。通过此功能,您可以测试依赖于框架的代码,而无需使用模拟器或模拟对象。Robolectric 支持 Android 平台的以下几个方面:

  • 组件生命周期
  • 事件循环
  • 所有资源

1.1插桩单元测试

您可以在物理设备或模拟器上运行插桩单元测试。不过,这种形式的测试所用的执行时间明显多于本地单元测试,因此,最好只有在必须根据实际设备硬件评估应用的行为时才依靠此方法。

运行插桩测试时,AndroidX Test 会使用以下线程:

  • 主线程,也称为“界面线程”或“Activity 线程”,界面交互和 Activity 生命周期事件发生在此线程上。
  • 插桩线程,大多数测试都在此线程上运行。当您的测试套件开始时,AndroidJUnitTest 类将启动此线程。

如果您需要在主线程上执行某个测试,请使用 @UiThreadTest 注释该测试。

2.编写中型测试

从模块级别验证应用的行为。 请编写中型测试,即用于验证一组单元的协作和交互的集成测试。

您可以根据应用的结构和以下中型测试示例(按范围递增的顺序)来定义表示应用中的单元组的最佳方式:

  1. 视图和视图模型之间的互动,如测试 Fragment 对象、验证布局 XML 或评估 ViewModel 对象的数据绑定逻辑。
  2. 应用的代码库层中的测试,验证不同数据源和数据访问对象 (DAO) 是否按预期进行互动。
  3. 应用的垂直切片,测试特定屏幕上的互动。此类测试目的在于验证应用堆栈的所有各层的互动。
  4. 多 Fragment 测试,评估应用的特定区域。与本列表中提到的其他类型的中型测试不同,这种类型的测试通常需要真实设备,因为被测互动涉及多个界面元素。

如需执行这些测试,请执行以下操作:

  1. 使用 Espresso-Intents 库中的方法。如需简化传入这些测试的信息,请使用虚假对象和打桩。
  2. 结合使用 IntentSubject 和基于 Truth 的断言来验证捕获的 intent。

2.1 运行插桩中型测试时使用 Espresso

当您在设备或 Robolectric 上执行类似于下面的界面互动时,Espresso 有助于使任务保持同步:

  • View 对象执行操作。
  • 评估具有无障碍功能需求的用户如何使用您的应用。
  • 找到并激活 RecyclerViewAdapterView 对象中的项。
  • 验证传出 intent 的状态。
  • 验证 WebView 对象中 DOM 的结构。

如需详细了解这些互动以及如何在应用的测试中使用它们,请参阅 Espresso 指南。

3.编写大型测试

单独测试应用中的每个类和模块很重要,但验证可引导用户使用多个模块和功能的端到端工作流也同样重要.

3.1 Espresso 中的同步支持

除了支持中型插桩测试之外,Espresso 还支持在大型测试中完成以下任务时实现同步:

  • 完成跨应用的进程界限的工作流。仅适用于 Android 8.0(API 级别 26)及更高版本。
  • 跟踪应用中长时间运行的后台操作。
  • 执行设备外测试。

如需详细了解这些互动以及如何在应用的测试中使用它们,请参阅 Espresso 指南。

3.使用 AndroidX Test 完成其他测试任务

1.使用 Truth 创建更容易读懂的断言

Guava 团队提供了一个名为 Truth 的流利断言库。在构建测试的验证步骤(或 then 步骤)时,您可以使用此库来代替基于 JUnit 或 Hamcrest 的断言。

  • assertThat(object).hasFlags(FLAGS)
  • assertThat(object).doesNotHaveFlags(FLAGS)
  • assertThat(intent).hasData(URI)
  • assertThat(extras).string(string_key).equals(EXPECTED)

AndroidX Test 支持 Android 的其他几个主题,以使基于 Truth 的断言更易于构建:

  • BundleSubject
  • IntentSubject
  • MotionEventSubject
  • NotificationActionSubject
  • NotificationSubject
  • PendingIntentSubject
  • PointerCoordsSubject
  • PointerPropertiesSubject

2. 编写界面测试

Espresso 可让您以编程方式且以线程安全的方式找到应用中的界面元素并与之互动。要了解详情,请参阅 Espresso 指南。

3. 运行界面测试

AndroidJUnitRunner 类定义了一个基于插桩的 JUnit 测试运行程序,可让您在 Android 设备上运行 JUnit 3 或 JUnit 4 型测试类。该测试运行程序可帮助您将测试软件包和被测应用加载到设备或模拟器上、运行测试并报告结果。

如需进一步提高这些测试的可靠性,请使用 Android Test Orchestrator,它在自己的 Instrumentation 沙盒中运行每个界面测试。这种架构减少了测试之间的共享状态,并在每个测试的基础上隔离了应用崩溃。如需详细了解 Android Test Orchestrator 在测试应用时提供的优势,请参阅 Android Test Orchestrator 指南。

4. 推动 Activity 和 Fragment 生命周期

您可以使用 ActivityScenarioFragmentScenario 类来测试应用的 Activity 和 Fragment 如何响应系统级中断和配置更改。如需了解详情,请参阅关于如何测试 Activity 和测试 Fragment 的指南。

5. 管理服务生命周期

AndroidX Test 包含用于管理关键服务的生命周期的代码。如需详细了解如何定义这些规则,请参阅 JUnit4 规则指南。

如果应用的行为取决于设备的 SDK 版本,请使用 @SdkSuppress 注释,并根据应用逻辑的分叉方式传入 minSdkVersionmaxSdkVersion 的值:

 @Test
 @SdkSuppress(maxSdkVersion = 27)
 public void testButtonClickOnOreoAndLower() {
 // ...
 }

你可能感兴趣的:(android进阶,单元测试,android)