赞
踩
测试应用是应用开发过程中不可或缺的一部分。通过持续对应用运行测试,您可以在公开发布应用之前验证其正确性、功能行为和易用性。
测试还会为您提供以下优势:
用户可以在各个层面与您的应用进行互动,从按某个按钮到将信息下载到他们的设备上。因此,在迭代开发您的应用时,您应测试各种用例和交互。
随着应用的扩展,您可能会发现有必要从服务器获取数据、与设备的传感器进行交互、访问本地存储或呈现复杂的界面。应用的多功能性需要全面的测试策略。
> 迭代创建和测试代码
迭代开发某项功能时,您可以先编写一个新测试,也可以将用例和断言添加到现有单元测试。测试最初会失败,因为该功能尚未实现。
务必考虑随着设计新功能而出现的责任单元。对于每个单元,您需要编写相应的单元测试。您的单元测试应几乎囊括与单元的所有可能的互动,包括标准互动、无效输入以及资源不可用的情况。应尽可能利用 Jetpack 库;当您使用这些经过充分测试的库时,您可以专注于验证您的应用特有的行为。
完整的工作流(如图 1 所示)包含一系列嵌套的迭代周期,其中一个由界面驱动的漫长而缓慢的周期用来测试代码单元的集成。您可以使用更短且更快的开发周期来测试单元本身。这一组周期一直持续到您的应用满足每个用例为止。
> 将应用看作一系列模块
为了使您的代码更易于测试,应从模块的角度进行开发,其中每个模块代表用户在您的应用中完成的一项特定任务。这种开发角度与基于堆栈的应用视图(通常包含代表界面、业务逻辑和数据的层)形成对比。
务必在每个模块周围设置明确定义的界限,并随着应用规模和复杂性的增长而创建新模块。每个模块应只重点关注一个领域,并且用于模块间通信的 API 应保持一致。为更轻松、快捷地测试这些模块间的交互,不妨考虑创建模块的虚假实现。在测试中,一个模块的真实实现可以调用另一个模块的虚假实现。
设置在应用中创建测试所需的环境和依赖项时,请遵循本部分中所述的最佳做法。
Android Studio 中的典型项目包含两个用于放置测试的目录。请按以下方式组织整理您的测试:
在设备上运行测试时,您可以从以下类型中进行选择:
创建测试时,您可以选择创建真实对象或测试替身,如虚假对象或模拟对象。通常,在测试中使用真实对象比使用测试替身要好,尤其是当被测对象满足以下某个条件时:
配置完测试环境后,就该编写用来评估应用功能的测试了。本部分介绍如何编写小型、中型和大型测试。
测试金字塔(如图 2 所示)说明了应用应如何包含三类测试:
沿着金字塔逐级向上,从小型测试到大型测试,各类测试的保真度逐级提高,但维护和调试工作所需的执行时间和工作量也逐级增加。因此,您编写的单元测试应多于集成测试,集成测试应多于端到端测试。虽然各类测试的比例可能会因应用的用例不同而异,但我们通常建议各类测试所占比例如下:小型测试占 70%,中型测试占 20%,大型测试占 10%。
您编写的小型测试应该是高度集中的单元测试,能够详尽地验证应用中每个类的功能和约定。
在特定类中添加和更改方法时,请针对它们创建和运行单元测试。如果这些测试依赖于 Android 框架,请使用与设备无关的统一 API,如 androidx.test API。这种一致性可让您在本地运行测试,而无需使用物理设备或模拟器。
如果您的测试依赖于资源,请在 应用的 build.gradle 文件中启用 includeAndroidResources
选项。然后,您的单元测试可以访问编译版本的资源,从而使测试更快速且更准确地运行。
app/build.gradle
- android {
- // ...
-
- testOptions {
- unitTests {
- includeAndroidResources = true
- }
- }
- }
# 本地单元测试
尽可能使用 AndroidX Test API,以便您的单元测试可以在设备或模拟器上运行。对于始终在由 JVM 驱动的开发计算机上运行的测试,您可以使用 Robolectric。
Robolectric 会模拟 Android 4.1(API 级别 16)或更高版本的运行时环境,并提供由社区维护的虚假对象(称为“影子”)。通过此功能,您可以测试依赖于框架的代码,而无需使用模拟器或模拟对象。Robolectric 支持 Android 平台的以下几个方面:
# 插桩单元测试
您可以在物理设备或模拟器上运行插桩单元测试。不过,这种形式的测试所用的执行时间明显多于本地单元测试,因此,最好只有在必须根据实际设备硬件评估应用的行为时才依靠此方法。
运行插桩测试时,AndroidX Test 会使用以下线程:
AndroidJUnitTest
类将启动此线程。如果您需要在主线程上执行某个测试,请使用 @UiThreadTest 注释该测试。
除了通过运行小型测试来测试应用的每个单元之外,您还应从模块级别验证应用的行为。为此,请编写中型测试,即用于验证一组单元的协作和交互的集成测试。
您可以根据应用的结构和以下中型测试示例(按范围递增的顺序)来定义表示应用中的单元组的最佳方式:
如需执行这些测试,请执行以下操作:
# 运行插桩中型测试时使用 Espresso
当您在设备或 Robolectric 上执行类似于下面的界面互动时,Espresso 有助于使任务保持同步:
如需详细了解这些互动以及如何在应用的测试中使用它们,请参阅 Espresso 指南。
尽管单独测试应用中的每个类和模块很重要,但验证可引导用户使用多个模块和功能的端到端工作流也同样重要。这些类型的测试会在您的代码中形成不可避免的瓶颈,但您可以通过验证尽可能接近实际成品的应用来最大限度地减轻这种影响。
注意:对于您编写的每个基于工作流的大型测试,您还应编写中型测试来检查工作流中包含的每个模块的功能。这种测试结构可让您更轻松地确定关键用户操作流程的哪一步出现意外行为。
如果您的应用足够小,您可能只需要一套大型测试来评估应用的整体功能。否则,您应按团队所有权、功能垂直领域或用户目标来划分大型测试套件。
通常,最好在模拟设备或基于云的服务(如 Firebase 测试实验室)上而不是在物理设备上测试您的应用,因为这样您可以更方便快捷地测试屏幕尺寸和硬件配置的多种组合。
# Espresso 中的同步支持
除了支持中型插桩测试之外,Espresso 还支持在大型测试中完成以下任务时实现同步:
如需详细了解这些互动以及如何在应用的测试中使用它们,请参阅 Espresso 指南。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。