Robolectric 单元测试仅在运行多模块单元测试运行配置时使用旧资源而不是二进制资源

Sea*_*ici 7 unit-testing robolectric android-resources android-studio

我有一个多模块 android 项目。我在每个模块中有一堆单元测试,我总是能够使用这样的运行配置一次运行它们:

在此处输入图片说明

我的许多测试使用一个与 RobolectricTestRunner 一起运行的基类。这个基类看起来像这样:

@RunWith(RobolectricTestRunner::class)
@Config(application = AndroidTest.ApplicationStub::class,
        manifest = Config.NONE,
        sdk = [21])
abstract class AndroidTest {
    @Suppress("LeakingThis")
    @Rule @JvmField val injectMocks = InjectMocksRule.create(this@AndroidTest)

    fun application(): Application = ApplicationProvider.getApplicationContext()

    internal class ApplicationStub : Application()
}
Run Code Online (Sandbox Code Playgroud)

**使用上述配置运行这些测试时,出现错误**

[Robolectric] NOTICE: legacy resources mode is deprecated; see http://robolectric.org/migrating/#migrating-to-40
Run Code Online (Sandbox Code Playgroud)

这使我的许多测试因 ResourceNotFoundException 而失败

但是,当我仅在特定模块中运行测试时,一切都会过去。这是因为 Robolectric 现在使用二进制资源:

[Robolectric] sdk=21; resources=BINARY
Run Code Online (Sandbox Code Playgroud)

我遵循了每个模块的 build.gradle 文件中的迁移说明,在每个 android 块中添加了以下内容:

testOptions {
    unitTests {
        includeAndroidResources = true
        returnDefaultValues = true
    }
}
Run Code Online (Sandbox Code Playgroud)

我发现但无法修复的一条线索是,当我运行 ALL UNIT TEST 任务时:

WARNING: No manifest file found at build/intermediates/merged_manifests/debug/../../library_manifest/debug/AndroidManifest.xml.
Falling back to the Android OS resources only.
No such manifest file: build/intermediates/merged_manifests/debug/../../library_manifest/debug/AndroidManifest.xml
To remove this warning, annotate your test class with @Config(manifest=Config.NONE).
Run Code Online (Sandbox Code Playgroud)

如您所见,我已尝试添加 manifest=Config.NONE,但它没有任何效果(现在已弃用)。

编辑:还尝试了 android.enableUnitTestBinaryResources = true 在 settings.gradle 中,但这会阻止应用程序构建,因为它是当前 gradle 工具中已弃用的标志。

感谢您提供的任何帮助!

Sea*_*ici 0

因此,随着 Android Studio 中默认的单元测试运行平台更改为 Gradle,我设法找到一种同时在多个模块中运行单元测试的方法,从而规避了 Robolectric bug。

在此输入图像描述

首先,进入运行配置并创建一个新的 Gradle 配置。

然后,作为 gradle 项目,选择顶级项目。对于参数,请使用 --tests "*"

现在对于 gradle 任务来说,这更容易出错。以下是我如何为我的项目进行设置的示例:

:androidrma:cleanTestGoogleDebugUnitTest :androidrma:testGoogleDebugUnitTest 
:calendar:cleanTestDebugUnitTest :calendar:testDebugUnitTest 
:gamification:cleanTest :gamification:test 
:player:cleanTest :player:test 
:playlists:cleanTest :playlists:test 
:sleepjournal:cleanTest :sleepjournal:test 
:sound-content-filters:cleanTest :sound-content-filters:test
Run Code Online (Sandbox Code Playgroud)

请注意,为了更清楚起见,我在每个模块之间插入了新行,在任务中,只需用空格分隔每个条目。

对于您的应用程序模块(在我的例子中名为 androidrma),您必须在 cleanTestUnitTest 和 testUnitTest 中使用构建变体名称,在我的例子中是 GoogleDebug。

如果我们看一下日历模块,它是一个android模块,所以它仍然以与appModule相同的逻辑运行。

然而,如果你看一下播放器、播放列表、睡眠日志等,这些都是纯 kotlin 模块。因此,这些任务的语法有所不同。

输入所有这些信息并且一切正常后,我建议选中运行配置设置屏幕右上角的“存储为项目文件”复选框。

这适用于 Android Studio 4.2 和 Arctic Fox,尚未在其他版本上进行测试。