【问题标题】:UI instrumentation tests with proguard enabled启用 proguard 的 UI 检测测试
【发布时间】:2018-08-21 01:31:36
【问题描述】:

假设您的应用有一个 Foo 类,并且您在您的应用和检测代码上使用这个类。

但此类在应用 APK 中变得模糊,因此您的检测代码会丢失对它的引用。

是否可以在使用检测代码的同时继续混淆类?

为了说明,考虑以下案例。

您的项目具有以下构建文件:

apply plugin: 'com.android.application'
android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "ademar.testproguard"
        minSdkVersion 21
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        resConfigs "en"
    }
    buildTypes {
        all {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt')
            testProguardFile "proguard-test-rules.pro"
        }
    }
}
dependencies {
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
}

proguard-test-rules:

-dontobfuscate
-dontwarn
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-ignorewarnings
-keepattributes *Annotation*
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn android.test.**
-dontwarn android.support.test.**

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="ademar.testproguard"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:name=".App"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

App 类:

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        new Foo().foo();
    }

}

一个将被混淆的简单类:

public class Foo {

    public void foo() {
        Log.d("TestProguard", "Success called");
    }

}

用户界面测试:

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    @Test
    public void testA() throws Exception {
        Context appContext = InstrumentationRegistry.getTargetContext();
        assertEquals("ademar.testproguard", appContext.getPackageName());
    }

    @Test
    public void testB() throws Exception {
        new Foo().foo();
    }

}

现在,如果您运行测试,testA 将通过,注意 App 已创建,已调用混淆的 Foo 类,并且您记录 Success called 已成功调用。 另一方面,testB 将收到以下异常:

java.lang.NoClassDefFoundError: Failed resolution of: Lademar/testproguard/Foo;
   at ademar.testproguard.ExampleInstrumentedTest.testB(ExampleInstrumentedTest.java:23)
   at java.lang.reflect.Method.invoke(Native Method)
   at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
   at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
   at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
   at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
   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:58)
   at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:375)
   at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2075)
Caused by: java.lang.ClassNotFoundException: Didn't find class "ademar.testproguard.Foo" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/system/framework/android.test.mock.jar", zip file "/data/app/ademar.testproguard.test-yIIGwW8RoqUKvzfKeMd__Q==/base.apk", zip file "/data/app/ademar.testproguard-L6M8bDawepTV9VltDF2TqA==/base.apk"],nativeLibraryDirectories=[/data/app/ademar.testproguard.test-yIIGwW8RoqUKvzfKeMd__Q==/lib/x86, /data/app/ademar.testproguard-L6M8bDawepTV9VltDF2TqA==/lib/x86, /system/lib, /vendor/lib]]
   at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:312)

如您所见,应用 APK 混淆了 Foo 类

Instrumentation 类也有 Foo,没有混淆它:

【问题讨论】:

  • 你能和我们分享一下你最后做了什么吗?
  • @IslamSalah 不幸的是,我放弃了,我关闭了 UI 测试的 proguard :(

标签: android testing proguard instrumentation


【解决方案1】:

您应该从 tour build.gradle 中删除 'testProguardFile "proguard-test-rules.pro"'。它包含“dontobfuscate”,可以有效地禁用您的测试 apk 上的混淆。

注意:我无法验证这个正确的 niet

【讨论】:

    猜你喜欢
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 2021-08-14
    • 1970-01-01
    • 2015-12-13
    • 2010-09-05
    相关资源
    最近更新 更多