Android 没有模拟器的集成测试

Android Integration tests without emulator

我想知道是否有一个选项可以测试使用 Android(模拟)并在某些端点上调用后端 运行 的客户端库?

用例可以是:

有一个名为 'A' 的库,它需要 android 的上下文(从中提取数据)和 Google 服务(可以是模拟的)。然后调用 A.sendData(context) 收集广告 id、phone 信息、...

等数据

所以测试生命周期可以是:

A.sendData(context) → waits for server response → assert result.

我到处都读到 Robolectric 不能用作集成框架。我已经用一些 UI 创建了一个 Instrumented 测试,它起到了作用但是 运行 它需要很长时间并且不能在远程 CI 上正常工作(超时,有时它会通过有时它不会'吨)。

我需要模拟 Android 设备的 'just' 部分(不需要 UI)并测试后端是否 returns 有效数据,所以可能不需要模拟器。或者,如果需要模拟器,我想创建一个使用模拟器的测试,但不需要编写 UI test.

有这样的吗?

在我看来,您要做的就是验证网络组件向服务器发送适当的数据并处理适当的响应。对于这种测试,我觉得Robolectric就可以满足需求了。它应该能够填充您的应用程序的上下文,然后可以将其注入到您的组件中。同时通过 JUnit 框架运行,这比仪器测试快得多。

不过,如果您要做的只是确保您的网络组件正常工作。那么你可能实际上不需要 Android 框架。您可以改为使用纯 Java 重写 class。只需从 Context 中删除您需要的项目,然后将它们注入到您的 classes 中。然后你可以在计算机而不是设备上使用 运行s 的 JUnit 测试框架。它要快得多,而且不需要 phone。只要它们不是 Android 特定组件(例如 Drawable),此方法就有效。如果您需要 Google 服务,这也将不起作用。

一个非常繁琐的方法是使用Mockito and PowerMock 模拟您的上下文和播放服务的方法。您只需模拟您的 Context class 将要使用的方法。但这可能会变得非常复杂。您可以将它与 Robolectric 一起使用,因此您只需要模拟您需要模拟的内容。

就集成测试而言,写集成测试完全没必要写UI测试。基本上,集成测试所做的是创建一个 运行 在 phone 上的测试应用程序。如果您不提供 UI,那么您将不会使用 UI。它只会在测试 运行 时显示空白屏幕。您可以使用 InstrumentationRegistery#getContext() 检索应用程序中使用的上下文。然后将上下文注入到需要它的组件中。

不过,这有时甚至会很痛苦,即使没有任何 UI,仪器测试也需要更长的时间。但是,如果您想确保它与实际的 Android 上下文和实际的 Google 服务一起工作,这是最好的方法。

所以基本策略是在 JUnit 框架上使用 Robolectric 编写一大堆小而快速的单元测试,这可能是 运行 很多次。然后使用仪器框架编写全面的验证测试,以确保一切都能很好地协同工作。