启用了proguard的UI检测测试

时间:2018-03-12 22:14:18

标签: android testing proguard instrumentation

我们假设您的应用有一个类Foo,并且您在应用和仪器代码上使用此类。

但是这个类在app 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");
    }

}

UI测试:

@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类混淆为

Main apk

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

Instrumentation APK

1 个答案:

答案 0 :(得分:0)

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

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