Robolectric 是否需要 Java 9?

Does Robolectric require Java 9?

所有测试都通过了,但我收到以下警告。 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"
    }

只有当您针对 Android Q 进行测试时,您才必须在 Java 9 上 运行。检查 https://github.com/robolectric/robolectric/releases/tag/robolectric-4.3

上的兼容性部分

注释你的测试
@Config(sdk = Build.VERSION_CODES.O_MR1)

或 sdk = 27。注释可以位于 class 或导致错误的测试方法之上。

您可能仍会收到 Java 9 是必需的警告,但测试将 运行 针对支持的 SDK。

在您的测试中class,您需要使用@Config 以一个sdk 数组作为参数进行注释。

@Config(sdk = {Build.VERSION_CODES.O_MR1})
class SampleTest {}

对于 Kotlin

@Config(sdk = [Build.VERSION_CODES.O_MR1])
class SampleTest {}

您的测试应该 运行.

Robolectric 4.3.1 添加了对 API 29 的支持,但是...满足以下要求:

Running tests on Android API 29 now strictly requires a Java9 runtime or newer

因此,如果您的目标是 API 29 或更高,则必须 运行 您的 Robolectric 使用 Java9。


更新 28/07/21:在 Android Studio

中使用 Java 11

Android Studio Arctic Fox 2020.3.1(带有 AGP 7.0)现在捆绑 JDK 11 并配置 Gradle 默认使用它。

参考:

更新 26/08/20:在 Android Studio

中使用 Java 9

从 Android Studio 3.6.0 开始,您可以在 File/Project 结构对话框中毫无问题地设置 JDK9。

此外,Android Studio 也将在 4.2 (more info) 中开始使用 JDK 11。

旧答案:

遗憾的是,您还不能将 Android Studio 项目配置为使用 JDK9(因为 Android Studio 3.5.3):

但是您可以从测试 运行 配置 (Run / Edit Configuration) 将目标 JRE 更改为 JDK9:


保持 Robolectric 与 Java 8

如果您不想/不能使用 Java 9,有几个变通方法可以 运行 使用 Java 8 进行测试:

配置Robolectric在整个项目中模拟下一个SDK:

  1. app/src/test/resources 下创建一个 robolectric.properties 文件。
  2. 在文件中添加以下内容以模拟 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 class 文件)。尝试在 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 class 文件。因为 Robolectric 使用这些框架 Jar,所以无法绕过 Java 9+ JVM。 (more info)

//对于 Kotlin

@Config(sdk = [Build.VERSION_CODES.O_MR1])

@RunWith(RobolectricTestRunner::class)

class MainActivityTest { }

在 Kotlin 中,要删除警告,请添加以下注释。

@Config(manifest = Config.NONE)
@RunWith(RobolectricTestRunner::class)

class UserRepositoryTest {}