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 notes

26/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=28robolectric.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 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Robolectric使用(一)简单使用

Android单元测试系列-Robolectric

Android单元测试系列-Robolectric

尝试使用 Robolectric 测试 XML 解析时出错

Android:如何在 Robolectric 中测试 PDFView?

Robolectric 和 Android SDK 29