Android 应用测试基础知识

本页概述了测试 Android 应用的核心原则,包括 核心最佳做法及其好处。

测试的好处

测试是应用开发流程中不可或缺的一环。通过运行测试 始终如一地对照您的应用,您可以验证其正确性、功能 在公开发布应用前了解其行为和易用性。

您可以手动测试应用。您可以使用 更改系统语言,然后尝试生成 或遍历每个用户流。

然而,手动测试的扩展效果欠佳,并且很容易被忽略 应用行为回归自动化测试涉及使用各种工具 来为您执行测试,这种方法速度更快、可重复性更高,而且 在应用开发的早期阶段就提供更具实用价值的应用反馈 过程。

Android 中的测试类型

移动应用非常复杂,必须在许多环境中正常运行。如 因此有多种类型的测试

主题

例如,根据正文,有不同类型的测试:

  • 功能测试:我的应用是否符合预期?
  • 性能测试:是否快速高效地完成测试?
  • 无障碍功能测试:它是否能够与无障碍服务完美配合?
  • 兼容性测试:它是否能够在所有设备和 API 级别上正常运行?

范围

测试还会因大小或隔离程度而异:

  • 单元测试或小型测试仅验证应用的一小部分, 例如方法或类
  • 端到端测试或大型测试可在 例如整个屏幕或用户流
  • 中型测试介于两者之间,用于检查两个测试或 更多广告单元。
。 <ph type="x-smartling-placeholder">
</ph> 测试可以是小型、中型或大型测试。
图 1:典型应用中的测试范围。

您可以通过多种方式对测试进行分类。不过,最重要的区别在于 是供应用开发者运行测试的地方

插桩测试与本地测试

您可以在 Android 设备或另一台计算机上运行测试:

  • 插桩测试在 Android 设备上运行(无论是真机还是模拟)。 该应用与测试应用一起构建和安装,测试应用可注入命令并 读取状态。插桩测试通常是界面测试、启动应用 然后再与之互动
  • 本地测试在您的开发机器或服务器上执行,因此它们 也称为主机端测试。它们通常体积小、速度快,且相互隔离, 受测对象从应用的其余部分开始。
。 <ph type="x-smartling-placeholder">
</ph> 这些测试可以作为插桩测试在设备上运行,也可以作为开发机器上的本地测试运行。
图 2:不同类型的测试(因运行位置而异)。

并非所有单元测试都是本地测试,也并非所有端到端测试都在设备上运行。例如:

  • 大型本地测试:您可以使用在本地运行的 Android 模拟器,例如 名为 Robolectric
  • 小型插桩测试:您可以验证自己的代码能否与 框架功能,例如 SQLite 数据库。您可以在 检查与多个版本的 SQLite 的集成。

示例

以下代码段演示了如何在 插桩界面测试,该测试需点击某个元素,并验证另一个元素是否是另一个 元素。

Espresso

// When the Continue button is clicked
onView(withText("Continue"))
    .perform(click())

// Then the Welcome screen is displayed
onView(withText("Welcome"))
    .check(matches(isDisplayed()))

Compose UI

// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()

// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()

此代码段显示了 ViewModel(本地、主机端)的单元测试的一部分 测试):

// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)

// When data is loaded
viewModel.loadData()

// Then it should be exposing data
assertTrue(viewModel.data != null)

定义测试策略

在理想情况下,您会在每台设备上测试应用中的每一行代码 应用的兼容性遗憾的是,这种方法速度太慢, 代价高昂。

良好的测试策略能够在 速度和可靠性测试环境与 真实设备来决定测试的保真度。运行较高保真度测试的设备 模拟设备或实体设备本身。可能会运行较低的保真度测试 本地工作站的 JVM 上运行。高保真度测试通常较慢, 需要更多资源,因此并非每项测试都应该是高保真测试。

不稳定的测试

即使在正确设计和实现的测试运行中,也会出现错误。例如: 在真实设备上运行测试时,系统可能会在 并导致测试失败代码中细微的竞态条件可能会导致 只会发生很少一部分的情况。未通过 100% 的测试 不稳定

可测试的架构

使用可测试的应用架构时,代码遵循的结构 以便轻松地对它的不同部分单独进行测试可测试架构 例如更高的可读性、可维护性、可伸缩性和 可重用性。

不可测试的架构会生成以下内容:

  • 更大、更慢且更不稳定的测试。无法进行单元测试的类可能包含 大型集成测试或界面测试所涵盖的应用。
  • 测试不同场景的机会较少。测试越大,速度越慢 因此测试应用的所有可能状态可能不切实际。

如需详细了解架构指南,请参阅应用指南 架构

分离的方法

如果您可以从函数、类或模块的其余内容中提取部分函数、类或模块, 它变得更简单、更有效。这种做法称为分离, 是对可测试架构最重要的概念。

常见的分离方法包括:

  • 将应用拆分为多个,例如呈现层、层和数据层。您可以 也可以将应用拆分为多个模块,每个功能一个模块。
  • 避免向具有大型依赖项的实体添加逻辑,例如 activity 和 fragment。将这些类用作框架的入口点, 将界面和业务逻辑移到其他位置,例如可组合项、ViewModel 或 网域层
  • 避免在包含业务逻辑的类中使用直接框架依赖项。 例如,不要在 ViewModel 中使用 Android 上下文
  • 使依赖项易于替换。例如,使用 接口,而不是具体实现。使用 依赖项注入(即使您不使用 DI 框架)。

后续步骤

现在,您已经了解了为什么应该测试以及两种主要类型的测试,接下来, 请参阅测试内容

或者,如果您想创建第一个测试,并通过实际操作来学习,请查看 请参阅测试 Codelab