简体   繁体   English

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

[英]Best way to run fast JUnit tests in Android project in Android Studio

I have some plain old Java classes and simple JUnit tests in my Android Studio project. 我在Android Studio项目中有一些简单的旧Java类和简单的JUnit测试。 They currently live inside my Android Module. 他们目前住在我的Android模块中。 If I run them as Android tests they pass fine, but they're really slow as it requires launching or connecting to the emulator. 如果我将它们作为Android测试运行它们会很好地通过,但它们确实很慢,因为它需要启动或连接到模拟器。

If I try to run one as a JUnit test, I hit the !!! JUnit version 3.8 or later expected 如果我尝试运行一个作为JUnit测试,我点击!!! JUnit version 3.8 or later expected !!! JUnit version 3.8 or later expected JUnit version problem. !!! JUnit version 3.8 or later expected JUnit版本问题。 This answer explains how to workaround that issue. 答案解释了如何解决该问题。 Unfortunately, I then hit the java.lang.NoClassDefFoundError: junit/textui/ResultPrinter , which I can't figure out how to fix. 不幸的是,我然后点击java.lang.NoClassDefFoundError: junit/textui/ResultPrinter ,我无法弄清楚如何修复。

I then tried to move my JUnit tests into a separate Java module that depends on the Android Module. 然后我尝试将我的JUnit测试移动到依赖于Android模块的单独Java模块中。 Everything compiles fine. 一切都很好。 I added a new configuration to launch the JUnit tests (:MyJUnitTests:test), but the tests fail with package com.myproject.util does not exist . 我添加了一个新配置来启动JUnit测试(:MyJUnitTests:test),但测试失败, package com.myproject.util does not exist It looks like maybe the classpath isn't including the classes from the dependent Android Module. 看起来类似路径可能不包括依赖Android模块中的类。

Does anybody know how to fix this classpath issue? 有人知道如何解决这个类路径问题吗? I've looked at lots of related answers and none of them seem to work for me. 我看了很多相关的答案,但似乎没有一个对我有用。 Or is it a just a bad idea to try and keep my JUnit tests in their own Module? 或者尝试将JUnit测试保存在自己的模块中是一个坏主意?

I can get the JUnit tests to run fast and pass if I move my plain Java classes and their JUnit tests into a completely separate Module (eg here ), and reverse the dependency so the Android Module depends on the Java Module. 我可以让JUnit测试快速运行并传递,如果我将我的普通Java类及其JUnit测试移动到一个完全独立的模块(例如此处 ),并反转依赖性,以便Android模块依赖于Java模块。 Is that the preferred solution? 这是首选解决方案吗?

The basic problem is that Android Framework classes don't work well outside the context of Android OS, so any code that has dependencies on Framework classes doesn't run in a regular JUnit environment, as you've found. 基本问题是Android Framework类在Android OS的上下文之外不能很好地工作,因此任何依赖于Framework类的代码都不会在常规JUnit环境中运行,正如您所发现的那样。

Your solution of trying to move the JUnit tests into a separate module won't work because you can't have a plain Java module depend on an Android module. 您试图将JUnit测试移动到单独模块的解决方案将无法工作,因为您不能拥有依赖于Android模块的普通Java模块。 Android Gradle modules don't act like Java modules, because Android builds are much more complex, and because the end result of an Android module build will be an APK or an AAR, which other module types won't understand. Android Gradle模块不像Java模块那样,因为Android构建要复杂得多,并且因为Android模块构建的最终结果将是APK或AAR,其他模块类型将无法理解。

If you can move your plain Java classes and unit tests into a plain Java module and have the Android modules depend on that, it will be the best approach that will get the most support from official features in the IDE. 如果您可以将普通的Java类和单元测试移动到普通的Java模块中并让Android模块依赖于它,那么这将是获得IDE中官方功能支持的最佳方法。 It will also have an architectural benefit in that it will keep those classes free from Android abstractions, making it more portable, and enforcing a separation of business logic from UI or storage or other things more device-specific. 它还具有架构优势,因为它可以使这些类免于Android抽象,使其更具可移植性,并强制将业务逻辑与UI或存储或其他更具体设备的事物分离。

If that's difficult for you to do, then a lot of developers in your shoes go with Robolectric , which is a test harness allowing code depending on many parts of the Android Framework to run in a JUnit environment without an emulator or device. 如果你很难做到这一点,那么很多开发人员都会使用Robolectric ,这是一个测试工具,允许依赖Android框架的许多部分的代码在没有模拟器或设备的情况下在JUnit环境中运行。 It's not officially supported by Google, but Google is aware that it's widely used and tries hard to not wantonly break it. 它没有得到谷歌的官方支持,但谷歌意识到它已被广泛使用,并努力不要肆意破坏它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM