【问题标题】:Robolectric and Android Studio 1.1.0 and library testingRobolectric 和 Android Studio 1.1.0 和库测试
【发布时间】:2015-05-23 01:22:27
【问题描述】:

我无法让我的 Robolectric 单元测试在实验性 AS 1.1 单元测试变体下运行。我得到的错误如下所示;

java.lang.NoClassDefFoundError: com/my/app/R$string
    at com.my.app.MoneyFormatter.formatDealMessage(MoneyFormatter.java:63)
    ...
Caused by: java.lang.ClassNotFoundException: com.my.app.R$string
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at org.robolectric.bytecode.AsmInstrumentingClassLoader.loadClass(AsmInstrumentingClassLoader.java:100)
    ... 46 more

我通过从根目录(Snippet1 中的应用程序名称)的命令行执行命令来检索此错误;

./gradlew core:library:test

此方法适用于 Android Studio 1.1,但未启用单元测试并使用 v1.0 的 android gradle 工具 (com.android.tools.build:gradle:1.0.0)。

项目配置

我的项目具有如下规定的复杂结构;

应用程序名称 | |->应用 |->源 |-> androidTest // Espresso 助手类驻留在此处 |-> androidTestFlavour1 // 与 'flavour 1' 相关的 Espresso int 测试 |-> androidTestFlavour2 // 与 'flavour 2' 相关的 Espresso int 测试 |-> 风味1 |->风味2 |-> 主要 + AndroidManifest.xml // 应用程序清单 |-> testFlavour1 // 风味 1 的 Robolectric 单元测试 |-> testFlavour2 // 风味 2 的 Robolectric 单元测试 |->核心 |->图书馆 |-> 源 |-> main // 库代码位于此处 + AndroidManifest.xml |-> test // 库的 Robolectric 单元测试 +毕业 +gradlew +settings.gradle +local.properties

片段 1:项目示意图

我遵循了Pivotal Labs 自己的各种建议以及许多其他自制替代品,但没有成功。

错误是什么,我需要改变什么才能把它改正?

更新: 因此,在检查了用于运行测试的类路径后,我注意到了以下库路径;

  • /workspace/app/core/lib/build/intermediates/bundles/debug/classes.jar
  • /workspace/app/core/lib/build/intermediates/classes/test/debug
  • /workspace/app/core/lib/build/intermediates/dependency-cache/test/debug

这些目录都不包含生成的R$string.class 文件,因此出现异常。包含生成的“R”文件的目录包括应用程序的调试和发布构建类型。所以;

  • /workspace/app/core/lib/build/intermediates/classes/debug
  • /workspace/app/core/lib/build/intermediates/classes/release

这表明构建过程的一部分缺少添加“调试”或“发布”构建类型资源。这也支持了纯 Java 测试用例(仅依赖于 classes.jar)可以正常工作的行为。

【问题讨论】:

  • @EugenMartynov - 由于您提示查询类路径,我认为这个问题现在更加精细。阅读我的更新。 /debug/release 类没有与“测试”构建类型一起添加是否有原因?
  • 只是为了确认 - 调试文件夹根本没有任何类?
  • intermediates/debugintermediates/release 文件夹包含已编译的 java 类 (.class),intermediates/bundle/debug/ 包含包含 classes.jar。后者位于仅包含项目中的 Java 类的类路径中没有那些动态生成的(例如R.class),而前者在运行测试时从类路径中丢失。前者是否应该在类路径上是我最初的问题......
  • 我已经回答了这个问题 - 恢复到正常工作的 1.0 android 工具(而不是 1.1)添加了 build/intermediates/classes/debug - 这是这个问题的症结所在。现在如何强制 gradle 将此路径添加到类路径中以 100% 证明该理论?

标签: android unit-testing android-studio noclassdeffounderror robolectric


【解决方案1】:

好的!我已经让它工作了。我在库 build gradle 中添加了以下行,以强制将生成的“R”文件添加到测试类路径中;

sourceSets {
  test.java.srcDirs += "build/generated/source/r/debug"
}

有了这个,我已经达到了Robolectric测试的必杀技;

./gradlew core:lib:test

基于 Espresso 2.0 的集成;

./gradlew connectedAndroidTest

停止对 IDE 中的单元和集成测试支持的时钟......哦,那是什么? 7年?!爱未遗失。感谢this answer,它向我展示了如何强制向测试类路径添加内容。

【讨论】:

  • 太棒了!很高兴您找到了解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多