Robolectric 需要 Java 9 吗?
Posted
技术标签:
【中文标题】Robolectric 需要 Java 9 吗?【英文标题】:Does Robolectric require Java 9? 【发布时间】:2019-11-11 06:08:12 【问题描述】:所有测试都通过了,但我收到以下警告。 Robolectric 告诉我 Java 9 是必需的。我正在使用最新版本的 Robolectric。
[Robolectric] WARN: android SDK 10000 requires Java 9 (have Java 8). Tests won't be run on SDK 10000 unless explicitly requested.
[Robolectric] com.example.testcaseWithRobolectric.MainActivityTest.testAllElements: sdk=28; resources=BINARY
Called loadFromPath(/system/framework/framework-res.apk, true); mode=binary sdk=28
进程以退出代码 0 结束
这是我的 Gradle:
dependencies
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(path: ':domain_layer')
testImplementation "org.robolectric:robolectric:4.3"
defaultConfig
applicationId "com.example.testcaseWithRobolectric"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
【问题讨论】:
你是如何解决这个问题的? 【参考方案1】:在您的测试类上,您需要使用 @Config 注释,并使用 sdk 数组作为参数。
@Config(sdk = Build.VERSION_CODES.O_MR1)
class SampleTest
对于科特林
@Config(sdk = [Build.VERSION_CODES.O_MR1])
class SampleTest
您的测试应该会运行。
【讨论】:
如果您想针对您的应用支持的所有 SDK 版本(SDK 29 除外)运行测试,注释应该看起来有点不同:@Config(maxSdk = Build.VERSION_CODES.P)
Build.VERSION_CODES.P 等于 28,只是以防万一。
当我将 targetSdkVersion 更改为 29 时,这对我不起作用。为什么?我仍然想在 API 28 上运行测试。
对我来说需要这个改变:@Config(sdk = intArrayOf(Build.VERSION_CODES.O_MR1))
将此用于 Kotlin 并有效,@Config(sdk = [Build.VERSION_CODES.P]) 非常感谢。【参考方案2】:
Robolectric 4.3.1 增加了对 API 29 的支持,但是...具有以下要求:
在 Android API 29 上运行测试现在严格要求 Java9 运行时或更新版本
因此,如果您的目标是 API 29 或更高版本,则必须使用 Java9 运行您的 Robolectric。
28/07/21 更新:在 Android Studio 中使用 Java 11
Android Studio Arctic Fox 2020.3.1(带有 AGP 7.0)现在捆绑了 JDK 11 并将 Gradle 配置为默认使用它。
参考:
JDK 11 required to run AGP 7.0 Use Java 11 source code in your project Android Studio Arctic Fox | 2020.3.1 release notes26/08/20 更新:在 Android Studio 中使用 Java 9
从 Android Studio 3.6.0 开始,您可以在文件/项目结构对话框中毫无问题地设置 JDK9。
此外,Android Studio 也将在 4.2 (more info) 中开始使用 JDK 11。
旧答案:
很遗憾,您还不能将您的 Android Studio 项目配置为使用 JDK9(作为 Android Studio 3.5.3):
但是您可以将目标 JRE 从您的测试运行配置更改为 JDK9 (Run / Edit Configuration
):
使用 Java 8 保持 Robolectric
如果您不想/不能使用 Java 9,有几个解决方法可以使用 Java 8 运行您的测试:
将 Robolectric 配置为在整个项目中模拟较低的 SDK:
-
在
app/src/test/resources
下创建一个robolectric.properties
文件。
在文件中添加以下类似 Android API28 的内容:
robolectric.properties
sdk=28
注意:如果你有一个多模块项目,理论上你的项目根目录下可以有一个global robolectric.properties
。但我无法让它工作......所以,不幸的是,我不得不为每个模块复制文件,例如core/src/test/resources
.
文档:robolectric.properties file
配置 Robolectric 以在特定测试中模拟较低的 SDK:
如果您不想为整个项目配置模拟 SDK,您可以使用 Robolectric @Config
注释为单个测试配置它:
@RunWith(AndroidJUnit4::class)
@Config(sdk = [Build.VERSION_CODES.P])
class MyRobolectricTest ...
文档:@Config annotation
为什么 Robolectric 需要 Java 9 来支持 Android Q?
Robolectric 使用 AOSP 构建工具链来构建 Android 框架 JARS。对于 Q,Java 工具链已更新为使用 java9,从而生成 java9 字节码(版本 53 类文件)。尝试在 java8 SDK 上的 Q 上运行 Robolectric 测试将失败,并出现如下错误:
java.lang.UnsupportedClassVersionError: org/xmlpull/v1/XmlPullParser has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
Android Q 中的 Dx 也进行了更新,以支持 53 版类文件。因为 Robolectric 使用这些框架罐子,所以没有办法绕过需要 Java 9+ JVM。 (more info)
【讨论】:
Java 版本大于 9 也可以使用。在 Linux 上它可能看起来像这样:/lib/jvm/java-11-openjdk-amd64
.
这应该是选择的答案。特别是在共享单元和仪器测试时,这是一种更好的方法。
这是最直接的答案,也很有效。对于我的用例,我只需要在 app\src\test\resources
包内创建带有 sdk=28
的 robolectric.properties
,然后瞧【参考方案3】:
用
注释你的测试@Config(sdk = Build.VERSION_CODES.O_MR1)
或 sdk = 27。注释可以超出导致错误的类或测试方法。
您可能仍会收到需要 Java 9 的警告,但测试将针对支持的 SDK 运行。
【讨论】:
【参考方案4】:只有在针对 Android Q 进行测试时,您才必须在 Java 9 上运行。检查https://github.com/robolectric/robolectric/releases/tag/robolectric-4.3 上的兼容性部分
【讨论】:
即使我降级到 27 也会收到同样的警告。 这是一个警告,表示当您以 Android Q 为目标时必须使用 Java 9【参考方案5】://对于科特林
@Config(sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(RobolectricTestRunner::class)
类 MainActivityTest
【讨论】:
【参考方案6】:在 Kotlin 中,要删除警告,请添加以下注释。
@Config(manifest = Config.NONE)
@RunWith(RobolectricTestRunner::class)
class UserRepositoryTest
【讨论】:
以上是关于Robolectric 需要 Java 9 吗?的主要内容,如果未能解决你的问题,请参考以下文章