0

我正在尝试在发布构建类型上运行仪器测试。我的设置如下:

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 规则文件中,可以使测试运行并顺利通过。

有任何想法吗?

4

1 回答 1

0

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

...

  1. 任务 compileDebugWithJavaC 任务

  2. 任务 compileClassesAndResourcesWithR8ForDebug

  3. 任务 compileDebugTestWithJavaC

  4. 任务 compileClassesAndResourcesWithR8ForDebugTest

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

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 应用于 2. 当你用 R8 编译你的应用程序时

当您使用 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 中生成的伴生类那么容易。

于 2019-06-06T18:32:33.367 回答