首页 > 解决方案 > Android Gradle Plugin 3.6 & 4.0 R8 没有用 src / test 代替 src / main

问题描述

我运行Espresso测试MockRetrofit以测试应用程序中的 UI 流。测试Espresso依赖于交换Dagger ApiModule位于src/main/java/com/my/app/ApiModule

@Module(includes = [NetworkModule::class])
class ApiModule {

    @Provides
    @Singleton
    fun restApi(
        retrofit: Retrofit.Builder,
        @DefaultClientBuilder clientBuilder: OkHttpClient.Builder
    ): RestApi {
        val apiRetrofit = retrofit.client(clientBuilder.build()).build()
        return apiRetrofit.create<RestApi>(RestApi::class.java)
    }
}

假货ApiModule位于src/androidTest/java/com/my/app/ApiModule

@Module(includes = [NetworkModule::class])
class ApiModule {

    @Provides
    @Singleton
    fun restApi(
        retrofit: Retrofit.Builder,
        @DefaultClientBuilder clientBuilder: OkHttpClient.Builder
    ): RestApi {
        return MockApiModule.getApi(failureRate = FailureRate.NEVER, responseDelay = 500L)
    }
}

我刚刚升级到 AGP 3.6(然后升级到 4.0)。运行时测试仍然通过./gradlew connectedDebugAndroidTest。但我也有一个名为的构建配置debugMinified

buildTypes{
        ...

        debugMinified {
            minifyEnabled true
            debuggable true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-testing.pro'
            signingConfig signingConfigs.debug
        }
    ...
}

我用它来运行Espresso带有混淆 apk 的测试,以捕获 Pro-guard 相关的运行时错误。

现在,当我运行时,我的测试失败了,因为在分析 apk 后,./gradlew connectedDebugMinifiedAndroidTestAGP 没有交换 src 集中的假实现。androidTest它只是在main. 但同样,这只发生在缩小版本中。

上面的类ApiModule是我在运行 UI 测试时以这种方式换出的 5 个类之一。其他 4 个与此无关,Dagger也没有被换掉,所以我相对确定这不仅仅是一个Dagger问题。

这目前阻止我升级到 AGP 4.0,因此非常感谢任何帮助。

标签: androidandroid-gradle-plugindagger

解决方案


经过一些试验和错误,我能够通过添加@Keep到所有虚假和真实的实现类签名来解决这个问题

@Keep
@Module(includes = [NetworkModule::class])
class ApiModule {

    @Provides
    @Singleton
    fun restApi(
        retrofit: Retrofit.Builder,
        @DefaultClientBuilder clientBuilder: OkHttpClient.Builder
    ): RestApi {
        val apiRetrofit = retrofit.client(clientBuilder.build()).build()
        return apiRetrofit.create<RestApi>(RestApi::class.java)
    }
}
@Keep
@Module(includes = [NetworkModule::class])
class ApiModule {

    @Provides
    @Singleton
    fun restApi(
        retrofit: Retrofit.Builder,
        @DefaultClientBuilder clientBuilder: OkHttpClient.Builder
    ): RestApi {
        return MockApiModule.getApi(failureRate = FailureRate.NEVER, responseDelay = 500L)
    }
}

我仍然不确定为什么会这样,甚至为什么现在需要它。只是一个幸运的猜测。任何进一步的见解将不胜感激。


推荐阅读