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 默认使用它。
参考:
- 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 开始,您可以在 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:
- 在
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 {...}
为什么 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 {}
所有测试都通过了,但我收到以下警告。 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 11Android 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 开始,您可以在 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:
- 在
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 {...}
为什么 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 {}