自动化测试以多种方式帮助您提高应用质量。例如,它帮助您执行验证、捕获回归并验证兼容性。一个好的测试策略让您可以利用自动化测试来关注一个重要的好处:开发人员生产力。
当团队采用系统的测试方法并配合基础设施增强时,可以实现更高的生产力。这样做可以及时反馈代码的行为。一个好的测试策略会执行以下操作:
- 尽早发现问题。
- 执行速度快。
- 当需要修复时提供明确的指示。
本页将帮助您决定要实施哪种类型的测试、在哪里运行以及运行频率。
测试金字塔
您可以根据大小对现代应用程序中的测试进行分类。小型测试只关注代码的一小部分,因此它们快速可靠。大型测试范围广泛,需要更复杂的设置,难以维护。然而,大型测试具有更高的保真度*,它们可以一次发现更多问题。
*保真度是指测试运行时环境与生产环境的相似程度。

大多数应用应该有许多小型测试和相对较少的大型测试。每个类别中测试的分布应形成一个金字塔,数量更多的小型测试构成底部,数量较少的大型测试构成顶部。
最小化 Bug 成本
一个好的测试策略会最大限度地提高开发人员生产力,同时最大限度地降低发现 Bug 的成本。
考虑一个可能效率低下的策略示例。在这里,按大小划分的测试数量没有组织成金字塔。端到端大型测试过多,而组件 UI 测试过少。

这意味着在合并之前运行的测试太少。如果存在 Bug,测试可能无法在夜间或每周的端到端测试运行之前捕获它。
重要的是要考虑这对于识别和修复 Bug 的成本以及为什么将测试工作偏向于更小、更频繁的测试非常重要。
- 当 Bug 被单元测试捕获时,通常在几分钟内修复,因此成本较低。
- 端到端测试可能需要几天才能发现相同的 Bug。这可能会涉及多个团队成员,从而降低整体生产力并可能延迟发布。此 Bug 的成本更高。
话虽如此,低效的测试策略总比没有策略好。当 Bug 进入生产环境时,修复需要很长时间才能到达用户设备,有时甚至几周,因此反馈周期最长且成本最高。
可扩展的测试策略
测试金字塔传统上分为 3 类:
- 单元测试
- 集成测试
- 端到端测试。
然而,这些概念没有精确的定义,因此团队可能希望以不同的方式定义其类别,例如使用 5 层:

- 单元测试在主机上运行,并验证单个逻辑功能单元,不依赖于 Android 框架。
- 示例:验证数学函数中的差一错误。
- 组件测试验证模块或组件的功能或外观,独立于系统中的其他组件。与单元测试不同,组件测试的表面积扩展到单个方法和类之上的更高抽象级别。
- 示例:自定义按钮的截屏测试
- 功能测试验证两个或多个独立组件或模块之间的交互。功能测试更大、更复杂,通常在功能级别操作。
- 示例:验证屏幕中状态管理的UI 行为测试
- 应用测试以可部署二进制文件的形式验证整个应用的功能。它们是大型集成测试,使用可调试的二进制文件(例如可以包含测试钩子的开发版本)作为被测系统。
- 示例:可折叠设备中的 UI 行为测试以验证配置更改、本地化和无障碍功能测试
- 发布候选版本测试验证发布版本的功能。它们类似于应用测试,不同之处在于应用程序二进制文件经过精简和优化。这些是在尽可能接近生产环境(不将应用暴露给公共用户帐户或公共后端)中运行的大型端到端集成测试。
- 示例:关键用户旅程、性能测试
此分类考虑了保真度、时间、范围和隔离级别。您可以在多个层中拥有不同类型的测试。例如,应用测试层可以包含行为测试、截屏测试和性能测试。
范围 |
网络访问 |
执行 |
构建类型 |
生命周期 |
|
---|---|---|---|---|---|
单元 |
单个方法或类,依赖项最少。 |
否 |
本地 |
可调试 |
合并前 |
组件 |
模块或组件级别 多个类协同工作 |
否 |
本地 |
可调试 |
合并前 |
功能 |
功能级别 与其他团队拥有的组件集成 |
模拟 |
本地 |
可调试 |
合并前 |
应用 |
应用级别 与其他团队拥有的功能和/或服务集成 |
模拟 |
模拟器 |
可调试 |
合并前 |
发布候选版本 |
应用级别 与其他团队拥有的功能和/或服务集成 |
生产服务器 |
模拟器 |
精简发布版本 |
合并后 |
决定测试类别
根据经验法则,您应该考虑金字塔中可以为团队提供正确反馈级别的最低层。
例如,考虑如何测试此功能的实现:登录流程的 UI。根据您需要测试的内容,您将选择不同的类别:
被测对象 |
正在测试内容的描述 |
测试类别 |
测试类型示例 |
---|---|---|---|
表单验证器逻辑 |
一个类,根据正则表达式验证电子邮件地址并检查是否输入了密码字段。它没有依赖项。 |
单元测试 |
|
登录表单 UI 行为 |
一个表单带有一个按钮,仅在表单已验证时启用 |
组件测试 |
运行在Robolectric上的UI 行为测试 |
登录表单 UI 外观 |
遵循 UX 规范的表单 |
组件测试 |
|
与身份验证管理器集成 |
将凭据发送到身份验证管理器并接收可能包含不同错误的响应的 UI。 |
功能测试 |
|
登录对话框 |
当按下登录按钮时显示登录表单的屏幕。 |
应用测试 |
运行在Robolectric上的UI 行为测试 |
关键用户旅程:登录 |
使用测试帐户针对预发布服务器的完整登录流程 |
发布候选版本 |
运行在设备上的端到端 Compose UI 行为测试 |
在某些情况下,某些内容属于哪个类别可能带有主观性。测试向上或向下移动可能还有其他原因,例如基础设施成本、不稳定性以及测试时间过长。
请注意,测试类别并不决定测试类型,并且并非所有功能都必须在每个类别中进行测试。
手动测试也可以是您测试策略的一部分。通常,QA 团队执行发布候选版本测试,但他们也可以参与其他阶段。例如,对没有脚本的功能中的 Bug 进行探索性测试。
测试基础设施
测试策略必须由基础设施和工具支持,以帮助开发人员持续运行其测试并强制执行规则,确保所有测试都通过。
您可以根据范围对测试进行分类,以定义何时何地运行哪些测试。例如,遵循 5 层模型:
类别 |
环境(何地) |
触发器(何时) |
---|---|---|
单元 |
[本地][4] |
每次提交 |
组件 |
本地 |
每次提交 |
功能 |
本地和模拟器 |
合并前,在合并或提交更改之前 |
应用 |
本地、模拟器、1 部手机、1 部可折叠设备 |
合并后,在合并或提交更改之后 |
发布候选版本 |
8 部不同手机、1 部可折叠设备、1 部平板电脑 |
发布前 |
- 单元和组件测试在持续集成系统上为每个新提交运行,但仅针对受影响的模块。
- 所有单元、组件和功能测试在合并或提交更改之前运行。
- 应用测试在合并后运行。
- 发布候选版本测试每晚在手机、可折叠设备和平板电脑上运行。
- 在发布之前,发布候选版本测试在大量设备上运行。
当测试数量影响生产力时,这些规则可能会随时间而改变。例如,如果您将测试移至夜间运行,您可能会减少 CI 构建和测试时间,但您也可能会延长反馈周期。