Estoy tratando de habilitar proguard en mis pruebas de Android. Pero me enfrento a un problema extraño:
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 en la compilación de lanzamiento funciona; no estoy seguro de por qué es tan agresivo en las pruebas de Android. Idealmente, las clases de instrumentación no se eliminarían en absoluto.
Creo que el problema central es que androidTest es una unidad de compilación diferente. app/src/androidTest se ensambla en app-debug-androidTest.apk mientras que app/src/main se ensambla en app-debug.apk . Por lo tanto, Proguard durante assembleDebug no ve ni incluye app/src/androidTest en la construcción del gráfico de uso de "sacudida de árboles" porque no está disponible en el classpath. En la práctica, significa que el código de la aplicación al que se hace referencia en las pruebas solo se está eliminando.
Este tema se correlaciona con "¿Debo cambiar la visibilidad de privada a pública solo para el acceso de prueba?" dilema Según el tipo de pruebas que esté escribiendo, puede considerar:
release.apk Desafortunadamente, no conozco ninguna solución automática mágica en este momento (similar al complemento all-open ). Pero es posible resolver el problema de los métodos faltantes caso por caso.
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 - configuración para app/src/main y sus dependencias de implementationproguard-project-ext.txt : configuración para app/src/main que contiene -keep instrucciones para cada método/campo utilizado en las pruebas solo que proguard eliminó "falsamente". Prefiero mantenerlo por separado, para eliminar condicionalmente al publicar en Google Playproguard-test-project.txt : configuración para app/src/androidTest y sus dependencias de androidTestImplementation . Normalmente contiene -dontwarn net.bytebuddy.** y etc. Aunque tenga en cuenta que el apk de prueba no es compatible con multidex, por lo que es posible alcanzar el método de límite de 65k al incluir demasiadas dependencias.Consulte android/platform/tools/base/studio-master-dev/./build-system/integration-test/test-projects/minify para obtener la referencia de implementación.
Las compilaciones de test son , de forma predeterminada, siempre compilaciones de debug , incluso cuando se configura un testBuildType , esto tiene que tener config initWith debug , lo que sugiere otra configuración incorrecta. Lo siento por no proporcionar la respuesta esperada, pero esta configuración incorrecta se basa en una cierta concepción errónea. Sugeriría deshabilitar la ofuscación, porque en este caso no tiene sentido, porque este paquete nunca se distribuirá. es posible que ni siquiera sea posible definir las reglas de ProGuard para la aplicación de prueba (que es un paquete en sí mismo). este comportamiento es "por diseño", causado por trabajar contra el marco de prueba... porque la aplicación de prueba no sabrá sobre el mapeo de ofuscación de clase/método del otro paquete de aplicación y, por lo tanto, las posibilidades son bastante escasas, que esto podría alguna vez hacer ejercicio.
Firebase Test Lab Robo UX Test es lo más parecido a lo que efectivamente se demanda.