android - Gradle在运行Android工具时会忽略testProguardFile

标签 android gradle proguard instrumentation android-r8

我正在尝试在版本构建类型上运行检测测试。
我的设置如下:

Android Studio - 3.4.1
Android Gradle Plugin - 3.4.1
Gragle - 5.4.1
R8 - Enabled (default)

相关的 build.gradle 代码段:
    testBuildType "release"

    buildTypes {
        release {
            proguardFiles fileTree(dir: 'vendor', include: ['*.pro']).asList().toArray()
            debuggable true
            minifyEnabled true
            shrinkResources true
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            testProguardFile 'proguard-rules-test.pro'
            testCoverageEnabled false
        }
    }

proguard-rules-test.pro的内容(出于测试目的):
-keep public class ** { *; }

运行任何检测都会导致以下运行时异常:
com.MYAPP.debug E/InstrumentationResultPrinter: Failed to mark test No Tests as finished after process crash
com.MYAPP.debug E/MonitoringInstr: Exception encountered by: Thread[main,5,main]. Dumping thread state to outputs and pining for the fjords.
    java.lang.NoSuchMethodError: No virtual method setAppComponent(L/com/MYAPP/injection/AppComponent;)V in class L/com/MYAPP/data/common/MyApplication$Companion; or its super classes (declaration of 'com.MYAPP.data.common.MyApplication$Companion' appears in /data/app/com.MYAPP.debug-o3QrzyIOGC0Ko3XRS2fcxQ==/base.apk)
        at com.MYAPP.base.TestMyApplication.h(TestMyApplication.kt:20)
        at com.MYAPP.data.common.MyApplication.onCreate(MyApplication.kt:126)

( TestMyApplication 扩展了 MyApplication ,并由 AndroidJUnitRunner 调用)

-keep 行从 proguard-rules-test.pro 移到Proguard主规则文件中,可以使测试运行并顺利通过。

有任何想法吗?

最佳答案

从sgjesse的答案中可能并不明显,但这是在两个不同的地方发生的。在最小输入上运行仪器测试的任务大致如下:

...

  • 任务compileDebugWithJavaC任务
  • 任务compileClassesAndResourcesWithR8ForDebug
  • 任务compileDebugTestWithJavaC
  • 任务compileClassesAndResourcesWithR8ForDebugTest

  • 在上述任务中,1.和2.编译您的应用程序并使用R8对其进行优化,3.和4.编译您的测试并使用R8编译该测试,并将原始应用程序放在库路径中

    使用R8编译应用程序时,会将proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.txt'应用于2。

    当您使用R8编译测试时,将testProguardFile'proguard-rules-test.pro'应用于测试。这就是为什么将保留规则添加到“常规” proguard文件的原因,因为您将它们添加到很晚。

    如果要在运行调试时将规则应用到您的主应用程序,只需添加调试配置并在其中添加另一个文件:
    buildTypes{
      debug {
       ..
       proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-rules-test.pro'
      }
    

    在所有情况下,如果您添加-keep public class ** {*;,我都不明白您为什么要“测试”您的小型应用程序。 }。这基本上将阻止R8进行任何优化,因此您最好在没有minifyEnabled的情况下进行测试。理想情况下,您应该在应用程序中找到测试的入口点,然后仅添加这些入口点。对于kotlin中生成的伴随类,这当然不那么容易。

    关于android - Gradle在运行Android工具时会忽略testProguardFile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56391230/

    相关文章:

    java - 尝试在 RecyclerView 中使用 Glide 加载图像时出现错误 - "Cannot resolve symbol ' 上下文

    Android 的电子邮件和 GMail 应用程序从电子邮件中删除 HTML 格式

    Android AdMob 中介 - 不接收中介网络广告

    gradle - 无法确定 Gradle 为什么在配置阶段下载 compileClasspath 依赖项

    gradle - 按顺序执行子项目的gradle任务

    android - 如何在没有Internet和/或没有Gradle的情况下使用Mapbox Android SDK

    proguard:保留带有参数列表的方法

    android - Android 上的文件上次访问时间

    android - 如何将 Proguard 混淆模块导入 Android Studio?

    java - 如何使用 proguard 混淆除公共(public)方法名称和属性之外的所有内容?