启用proguard时,androidTest中没有静态方法deleteRecursively(Ljava / io / File;)

问题描述 投票:2回答:2

我想在我的android测试中启用proguard。但我面临一个奇怪的问题:

java.lang.NoSuchMethodError: No static method deleteRecursively(Ljava/io/File;)Z in class Lkotlin/io/FilesKt; or its super classes (declaration of 'kotlin.io.FilesKt' appears in /data/app/org.walleth.offline-BAciL8erjxU-sHGjQe6uQg==/base.apk!classes2.dex)
at org.ligi.trulesk.RulesKt.doBefore(Rules.kt:82)
at org.ligi.trulesk.RulesKt.access$doBefore(Rules.kt:1)
at org.ligi.trulesk.TruleskIntentRule.beforeActivityLaunched(Rules.kt:58)
at android.support.test.rule.ActivityTestRule.launchActivity(ActivityTestRule.java:351)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:525)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
at org.ligi.trulesk.AppReplacingRunnerBase.onStart(AppReplacingRunnerBase.kt:19)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2145)

发布版本的Proguard工作 - 不知道为什么它在android测试中如此激进。理想情况下,根本不会删除检测类。

java android kotlin proguard
2个回答
2
投票

我认为核心问题是androidTest是一个不同的编译单元。 app/src/androidTest组装成app-debug-androidTest.apk,而app/src/main组装成app-debug.apk。因此,在assembleDebug期间的Proguard既没有看到没有包括app/src/androidTest构建“树摇动”使用图,因为它在类路径上不可用。实际上,这意味着只有在测试中引用的应用程序代码才被规定。

本主题与“我是否应该仅针对测试访问更改从私人到公共的可见性?”相关联。两难困境。根据您所编写的测试类型,您可以考虑:

  • 始终将应用程序的额外入口点(由测试使用)保存在用户release.apk
  • 在运行测试时以不同方式编译主apk,并再次接受向用户发送的风险与测试运行的代码不完全相同

不幸的是,我目前还不知道任何自动魔术解决方案(类似于all-open插件)。但是有可能以个案的方式解决缺失的方法问题。

buildTypes {
    debug {
        minifyEnabled true

        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt', 'proguard-project-ext.txt'
        testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-test-project.txt'
    }
}      
  • proguard-project.txt - app/src/main的配置和它的implementation依赖
  • proguard-project-ext.txt - app/src/main的配置,其中包含-keep指令,用于仅在测试中使用的每个方法/字段,由proguard“错误地”删除。我希望单独保留它,以便在发布到Google Play时有条件地删除
  • proguard-test-project.txt - app/src/androidTest的配置和它的androidTestImplementation依赖。通常包含-dontwarn net.bytebuddy.**等。虽然注意,该测试apk不支持multidex,因此可以通过包含太多依赖项来命中65k限制方法。

检查android/platform/tools/base/studio-master-dev/./build-system/integration-test/test-projects/minify的实现参考。


0
投票

test构建是 默认情况下 总是debug构建 - 即使设置testBuildType,这必须有配置initWith debug,暗示其他错误的配置。很抱歉没有提供预期的答案,但这种错误的配置是基于某种误解。我建议禁用混淆,因为在这种情况下它是毫无意义的,因为这个包不会被分发。甚至可能无法为测试应用程序(它本身就是一个包)定义ProGuard规则。这种行为是“按设计”,由于对抗测试框架而导致......因为测试应用程序不会知道另一个应用程序包的类/方法混淆映射 - 因此可能性很小,这可能是一直在努力。

Firebase测试实验室qazxsw poi与实际需求最相似。

© www.soinside.com 2019 - 2024. All rights reserved.