Robolectric是否需要Java 9?

The*_*ian 16 android unit-testing robolectric

所有测试都通过了,但是我得到以下警告。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
Run Code Online (Sandbox Code Playgroud)

流程结束,退出代码为0

这是我的摇篮:

    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"
    }
Run Code Online (Sandbox Code Playgroud)

Dav*_*uel 81

Robolectric 4.3.1添加了对 API 29 的支持,但...具有以下要求:

在 Android API 29 上运行测试现在严格要求 Java9 运行时或更新版本

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


28 年 7 月 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 Structure 对话框中设置 JDK9。

JDK 9

此外,Android Studio 也将在 4.2 中开始使用 JDK 11(更多信息)。

旧答案:

不幸的是,您还不能将您的 Android Studio 项目配置为使用 JDK9(作为 Android Studio 3.5.3): 项目结构

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


使用 Java 8 保持 Robolectric

如果您不想/不能使用 Java 9,有几种解决方法可以使用 Java 8 运行您的测试:

在整个项目中配置 Robolectric 以模拟较低的 SDK:

  1. 下创建一个robolectric.properties文件app/src/test/resources
  2. 在文件中添加以下内容以模拟 Android API28:

robolectric.properties

sdk=28
Run Code Online (Sandbox Code Playgroud)

注意:如果你有一个多模块的项目,理论上你可以在你的项目的根目录下有一个全局robolectric.properties的。但我无法让它工作......所以,不幸的是,我不得不为每个模块复制文件,例如core/src/test/resources.

文档:robolectric.properties 文件

配置 Robolectric 以在特定测试中模拟较低的 SDK:

如果您不想为整个项目配置模拟 SDK,您可以使用 Robolectric@Config注释为单个测试配置它:

@RunWith(AndroidJUnit4::class)
@Config(sdk = [Build.VERSION_CODES.P])
class MyRobolectricTest {...}
Run Code Online (Sandbox Code Playgroud)

文档:@Config 注释


为什么 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
Run Code Online (Sandbox Code Playgroud)

Android Q 中的 Dx 也进行了更新,以支持版本 53 的类文件。因为 Robolectric 使用这些框架罐,所以没有办法要求 Java 9+ JVM。(更多信息

  • 这应该是选定的答案。特别是在共享单元和仪器测试时,这是一个更好的方法。 (5认同)

小智 14

在测试类上,您需要使用sdk数组作为参数的@Config进行注释。

@Config(sdk = [Build.VERSION_CODES.O_MR1])
class SampleTest {}
Run Code Online (Sandbox Code Playgroud)

您的测试应该运行。

  • 如果您想针对您的应用程序支持的所有 SDK 版本(SDK 29 除外)运行测试,则注释应该看起来有点不同:`@Config(maxSdk = Build.VERSION_CODES.P)` Build.VERSION_CODES.P 等于 28 , 万一。 (3认同)
  • 对我来说,需要进行此更改:@Config(sdk = intArrayOf(Build.VERSION_CODES.O_MR1)) (2认同)
  • 带括号的答案是错误的,后续不带括号的答案也是错误的。您应该使用大括号:@Config(sdk = [Build.VERSION_CODES.O_MR1]) (2认同)

Wry*_*day 8

注释您的测试

@Config(sdk = Build.VERSION_CODES.O_MR1)
Run Code Online (Sandbox Code Playgroud)

或sdk =27。注释可以超出导致错误的类或测试方法的上方。

您可能仍然会收到警告,要求使用Java 9,但是该测试将针对支持的SDK运行。


Eug*_*nov 6

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

  • 即使我降级到 27,我也会收到同样的警告。 (3认同)