本页概述了测试 Android 应用的核心原则,包括 核心最佳做法及其好处。
测试的好处
测试是应用开发流程中不可或缺的一环。通过运行测试 始终如一地对照您的应用,您可以验证其正确性、功能 在公开发布应用前了解其行为和易用性。
您可以手动测试应用。您可以使用 更改系统语言,然后尝试生成 或遍历每个用户流。
然而,手动测试的扩展效果欠佳,并且很容易被忽略 应用行为回归自动化测试涉及使用各种工具 来为您执行测试,这种方法速度更快、可重复性更高,而且 在应用开发的早期阶段就提供更具实用价值的应用反馈 过程。
Android 中的测试类型
移动应用非常复杂,必须在许多环境中正常运行。如 因此有多种类型的测试
主题
例如,根据正文,有不同类型的测试:
- 功能测试:我的应用是否符合预期?
- 性能测试:是否快速高效地完成测试?
- 无障碍功能测试:它是否能够与无障碍服务完美配合?
- 兼容性测试:它是否能够在所有设备和 API 级别上正常运行?
范围
测试还会因大小或隔离程度而异:
- 单元测试或小型测试仅验证应用的一小部分, 例如方法或类
- 端到端测试或大型测试可在 例如整个屏幕或用户流
- 中型测试介于两者之间,用于检查两个测试或 更多广告单元。
您可以通过多种方式对测试进行分类。不过,最重要的区别在于 是供应用开发者运行测试的地方
插桩测试与本地测试
您可以在 Android 设备或另一台计算机上运行测试:
- 插桩测试在 Android 设备上运行(无论是真机还是模拟)。 该应用与测试应用一起构建和安装,测试应用可注入命令并 读取状态。插桩测试通常是界面测试、启动应用 然后再与之互动
- 本地测试在您的开发机器或服务器上执行,因此它们 也称为主机端测试。它们通常体积小、速度快,且相互隔离, 受测对象从应用的其余部分开始。
并非所有单元测试都是本地测试,也并非所有端到端测试都在设备上运行。例如:
- 大型本地测试:您可以使用在本地运行的 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。