Espresso 空闲资源

空闲资源表示其结果会影响其结果的异步操作 界面测试中的后续操作。通过将空闲资源注册到 Espresso 进行编程时,您可以更可靠地验证这些异步操作, 测试您的应用

确定何时需要空闲资源

Espresso 提供了一套先进的 同步功能。这个 而这一框架的特色仅应用于 MessageQueue 上的消息,例如 在屏幕上绘制其内容的 View

因为 Espresso 不知道任何其他异步操作,包括 那些在后台线程上运行的应用,Espresso 无法提供其同步 提供保证。为了让 Espresso 知道应用的 长时间运行的操作,您必须将每个操作注册为空闲资源。

如果您在测试应用的结果时不使用空闲资源, 异步工作,您可能会发现自己必须使用 来改进测试可靠性:

  • 添加对 Thread.sleep() 的调用。当您 人为增加测试延迟,那么测试套件所需的时间 有时,测试在执行时仍可能会失败 运行速度较慢的设备此外,这些延迟并不能很好地进行调整,因为您的应用可能 必须在未来的版本中执行更耗时的异步工作。
  • 实现重试封装容器,使用循环来反复检查 您的应用仍在执行异步工作,直到发生超时。即使 您在测试中指定重试次数上限,每次重新执行都会消耗 尤其是 CPU
  • 使用 CountDownLatch 的实例, 允许一个或多个线程等待特定数量的操作 在另一个线程中执行的所有操作都已完成这些对象要求您指定 超时时长;否则,您的应用可能会被无限期屏蔽。开关 还会给代码增加不必要的复杂性,使维护更加困难。

Espresso 可让您从测试中移除这些不可靠的解决方法, 而是将应用的异步工作注册为空闲资源。

常见用例

在测试中执行与以下示例类似的操作时, 可以考虑使用空闲资源:

  • 从互联网或本地数据源加载数据
  • 与数据库和回调建立连接
  • 管理服务(使用系统服务或 IntentService
  • 执行复杂的业务逻辑,如位图转换。

在执行这些操作时注册空闲资源 更新测试随后会验证的界面。

空闲资源实现示例

以下列表介绍了空闲资源的几个实现示例 您可以集成到应用中

CountingIdlingResource
维护活动任务的计数器。当计数器为零时,相关联的 视为空闲资源该功能与 Semaphore。在大多数情况下,这种实现方式 以便在测试期间管理应用的异步工作。
UriIdlingResource
类似于 CountingIdlingResource, 但计数器必须在特定时间段内为零,才能 视为空闲资源这一额外的等待期将连续 而线程中的应用可能会发出新的 。
IdlingThreadPoolExecutor
ThreadPoolExecutor 的自定义实现 用于跟踪所创建的线程中正在运行的任务总数 资源池。此类使用 CountingIdlingResource至 维护活跃任务的计数器。
IdlingScheduledThreadPoolExecutor
自定义实现 ScheduledThreadPoolExecutor。它提供 Google Cloud 的 IdlingThreadPoolExecutor 类,但它也可以跟踪为将来安排的任务, 定期执行

创建您自己的空闲资源

当您在应用的测试中使用空闲资源时,您可能需要提供 自定义资源管理或日志记录在这些情况下, 可能不够。如果是这种情况,您可以 扩展其中一个空闲资源实现或创建自己的空闲资源实现。

如果您实现自己的空闲资源功能,请始终遵循以下最佳做法, 特别是第一种:

在空闲检查之外调用转换到空闲状态。
在应用进入空闲状态后, onTransitionToIdle() 任何 isIdleNow()。这样, Espresso 不会进行第二个不必要的检查来确定给定的 空闲资源处于空闲状态。

以下代码段说明了此建议:

Kotlin

fun isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

fun backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}

Java

public void isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

public void backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}
在需要之前注册空闲资源。

与空闲资源关联的同步优势仅生效 在 Espresso 首次调用该资源的 isIdleNow() 方法。

以下列表显示了此属性的几个示例:

  • 如果您在带有 @Before 注解的方法中注册了空闲资源, 空闲资源会在每个测试的第一行生效。
  • 如果您在测试中注册了空闲资源,该空闲资源 在下一项基于 Espresso 的操作期间生效。这种行为仍然 即使下一项操作与执行测试的语句在同一测试中, 注册空闲资源。
使用完空闲资源后将其取消注册。

为节约系统资源,您应该尽快取消注册空闲资源 因为您不再需要它们例如,如果您注册了空闲资源 则最好在带有 @Before 注解的方法中取消注册此资源, 相应的方法(带有 @After 注解)。

使用空闲资源注册表来注册和取消注册空闲资源。

通过使用此容器存储应用的空闲资源,您可以注册和 根据需要反复取消注册空闲资源,并且仍会观察到一致 行为

在空闲资源内仅维护简单的应用状态。

例如,您实现和注册的空闲资源不应 包含对 View 对象的引用。

注册空闲资源

Espresso 提供了一个容器类,您可以将应用的空闲状态置于其中 资源。此类称为 IdlingRegistry 是 给应用带来的开销极低的独立工件。类 还可以让您采取以下措施来改进 可维护性:

  • 创建对 IdlingRegistry(而不是空闲资源)的引用 。
  • 保持用于以下用途的空闲资源集合中的差异 每个 build 变体。
  • 在应用的服务中定义空闲资源,而不是在界面中定义 引用这些服务的组件

将空闲资源集成到应用中

尽管您可以通过多种不同的方式向应用添加空闲资源, 具体做法是,该方法会为您的应用维护封装,同时仍允许 您可以指定给定空闲资源表示的特定操作。

向应用添加空闲资源时,我们强烈建议您将空闲资源 应用本身中存在空闲资源逻辑,并且仅执行注册和 取消注册操作。

虽然您在 Google Cloud 中 将空闲资源封装在 代码,从而保持应用的 APK 大小和方法计数。

替代方法

如果您不希望应用的正式版中有空闲资源逻辑 代码,还有其他几种可行的集成策略:

  • 创建 build 变体,如 Gradle 的 build 变体 产品 变种,并且仅在应用的调试 build 中使用空闲资源。
  • 使用依赖项注入框架(如 Dagger)注入应用的空闲状态 资源依赖关系图添加到您的测试中。如果您使用的是 Dagger 2,则 注入本身应源自子组件。
  • 在应用的测试中实现空闲资源,并公开该部分 需要同步的 测试。

    注意 :尽管此设计决策似乎 创建对空闲资源的独立引用,也会破坏 封装在除最简单的应用之外的所有应用中。

其他资源

如需详细了解如何在 Android 测试中使用 Espresso,请查阅 以下资源。

示例