如何在 Kotlin Android UI 测试中初始化模拟的外部依赖项



我将在 Kotlin 中开发一个 Android 应用程序,我正在尝试弄清楚如何初始化模拟依赖项。 例如,该应用程序将对服务器进行API调用,从位置提供商处获取用户的位置,从内容管理系统中提取图像,将数据本地存储在数据库和Android的共享首选项中,并根据当前日期/时间进行数学运算。 因此,我想模拟很多外部依赖项,包括当前日期/时间,以便我可以验证年龄计算等。

我的测试目标只是使用 Android 检测测试来验证应用的屏幕。 我不希望依赖真正的外部系统,因为测试这些系统是这些系统的开发人员的责任。

在阅读 Android 文档 考虑是否使用测试替身时,我注意到它提供了一个很好的提示:"提示:请咨询库作者,看看他们是否提供了任何官方支持的测试基础设施,例如假的,你可以可靠地依赖。 但是,该文档并未真正解释如何初始化第三方测试基础结构。

以下是我到目前为止对我的选择的理解,但它们都回到了我不明白的基本问题上:被测试的 Android 应用程序如何知道它应该在测试模式下运行而不是在生产模式下运行?

  1. 像Mockito或MockK:Mocking这样的模拟似乎是为测试量身定制的依赖注入的特殊情况。 我看到的例子涉及测试一个类或一个方法,而不是一个完整的系统。 这些示例通常显示如何模拟类并将其传递给所测试的类/方法。 但是对于全尺寸系统,测试代码在通过Espresso引用的小部件上运行。 无法访问逻辑所在的类。 我的印象是嘲笑的是单元测试,而不是UI测试。 但也许有人可以解释如何使用模拟进行 UI 测试:

    • a) 假设外部依赖项在调用堆栈中深入初始化。 如果我在测试代码的设置函数中定义了一个模拟(例如,用@Before注释的方法),我如何将其传递到依赖于它的代码中的位置?

    • b) 我一直读到模拟在 Kotlin 中不起作用,因为 Kotlin 将所有类定义为最终类。 似乎有一些解决方法。 但是谷歌/安卓是否正式推荐其中之一(我没有在他们的文档中读到它)。

  2. 依赖注入,如 Dagger 2:如果模拟不适用于 UI 测试,那么我应该使用依赖注入吗? 据我了解,Dagger 2 似乎通过定义一个顶级组件和一个模块树来处理上面的问题 1.a,这些模块可以在堆栈的任何层提供依赖项。 为了进行测试,似乎我只会提供一个模拟真实依赖项的不同组件。

    • a) 在 Android 仪器化测试中,实例化专为测试而设计的 Dagger 2 组件。 如何确保使用组件而不是用于生产的组件?
  3. 启动测试
  4. 前准备:我可以看到如何自定义build.gradle以在启动应用程序之前准备测试环境。 例如,我可以向我的应用程序传递一个标志,以便在调用应用程序的 onCreate() 时,我可以配置我的系统以通过依赖注入、模拟甚至只是自定义实现来准备模拟依赖项。 例如,某些外部依赖项具有测试模式,我需要在其中传递一个标志,以便它们在测试模式下工作。 我不清楚这种事情如何与依赖注入或模拟相协调,但我想我可以看到如何使用这些机制作为包装器来传递测试标志。 在下面的帖子中,有人想嘲笑位置提供商,并为此修改了他们的build.gradle文件,以便在Android测试基础设施开始之前进行设置。 如何在使用uiautomator和浓缩咖啡执行AndroidTest之前在Android设备上设置允许模拟位置?

总之,我想使用 Espresso 的 Android 插桩测试来测试 Kotlin Android 应用程序的 UI,但我不知道如何设置测试,以便外部依赖项使用仿真代码而不是生产代码。 我应该使用模拟,依赖注入,还是通过build.gradle进行自定义? 有人可以帮助我把我的思维走上正轨吗?

经过大量搜索,我发现Android ActivityTestRule允许您推迟启动Activity。 这为测试代码提供了时间来初始化模拟依赖项,如 Android Kotlin 上的快速模拟 UI 测试中所述。

相关内容

  • 没有找到相关文章

最新更新