在Android Studio中的Android项目中运行快速JUnit测试的最佳方法

时间:2014-07-09 19:23:18

标签: android unit-testing junit gradle android-studio

我的Android Studio项目中有一些简单的旧Java类和简单的JUnit测试。他们目前住在我的Android模块中。如果我将它们作为Android测试运行它们会很好,但它们确实很慢,因为它需要启动或连接到模拟器。

如果我尝试运行一个作为JUnit测试,我遇到了!!! JUnit version 3.8 or later expected JUnit版本问题。这个answer解释了如何解决该问题。不幸的是,我接着java.lang.NoClassDefFoundError: junit/textui/ResultPrinter,我无法弄清楚如何修复。

然后我尝试将我的JUnit测试移动到依赖于Android模块的单独Java模块中。一切都很好。我添加了一个新配置来启动JUnit测试(:MyJUnitTests:test),但测试失败了package com.myproject.util does not exist。看起来类似路径可能不包括依赖Android模块的类。

有人知道如何修复此类路径问题吗?我看了很多相关的答案,但似乎没有一个对我有用。或者尝试将JUnit测试保存在自己的模块中是一个坏主意吗?

如果我将普通Java类及其JUnit测试移动到一个完全独立的模块(例如here),我可以让JUnit测试快速运行并传递,并反转依赖性,以便Android模块依赖于Java模块。这是首选解决方案吗?

1 个答案:

答案 0 :(得分:8)

基本问题是Android Framework类在Android OS的上下文之外不能正常工作,因此任何依赖于Framework类的代码都不能在常规的JUnit环境中运行,因为你&#39 ;发现了。

您尝试将JUnit测试移动到单独的模块中的解决方案无法正常工作,因为您无法使用依赖于Android模块的普通Java模块。 Android Gradle模块不像Java模块那样,因为Android构建要复杂得多,并且因为Android模块构建的最终结果将是APK或AAR,其他模块类型不会理解。

如果您可以将普通的Java类和单元测试移动到普通的Java模块中并让Android模块依赖于它,那么这将是获得IDE中官方功能支持的最佳方法。它还具有架构优势,因为它可以使这些类免于Android抽象,使其更具可移植性,并强制将业务逻辑与UI或存储或其他更具体设备的事物分离。

如果您很难做到这一点,那么很多开发人员都会使用Robolectric,这是一个测试工具,允许代码依赖Android框架的许多部分来运行没有模拟器或设备的JUnit环境。它没有得到谷歌的正式支持,但谷歌意识到它已被广泛使用,并努力不要肆意破坏它。