仪器化Android单元测试和ProGuard

时间:2016-08-24 19:02:41

标签: android android-studio junit android-gradle android-testing

我有一个应用程序,我正在为它编写单元测试用例 我的测试用例提供了大量警告和1个错误 按照以下链接和子页面Building Instrumented Unit Tests

错误和一些警告

  

警告:有10个未解析的类或接口引用。            您可能需要添加缺少的库jar或更新其版本。            如果您的代码工作正常而没有丢失的类,则可以禁止            警告' -dontwarn'选项。            (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)   警告:根据程序类,有5个库类实例。            你必须避免这种依赖,因为程序类会            处理,而库类将保持不变。            (http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)   警告:程序类成员有3个未解析的引用。            您的输入类似乎不一致。            您可能需要重新编译代码。            (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)   警告:处理任务java.io.IOException时发生异常:请先纠正上述警告。   :app:transformClassesAndResourcesWithProguardForDebugAndroidTest FAILED

     

错误:任务':app:transformClassesAndResourcesWithProguardForDebugAndroidTest'执行失败。   java.io.IOException:请先纠正上述警告。

如果我从调试中删除proguard,我会收到64K错误!

  

错误:.dex文件中的方法引用数不能超过64K。   了解如何在https://developer.android.com/tools/building/multidex.html

解决此问题

我做错了什么?

app build.gradle

android {
compileSdkVersion 24
buildToolsVersion "23.0.3"

defaultConfig {
    applicationId "com.tyagiabhinav.xyz"
    minSdkVersion 16
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    debug {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'),   'proguard-rules.pro'
    }
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }
}
dependencies 
{
   compile fileTree(dir: 'libs', include: ['*.jar'])
   testCompile 'junit:junit:4.12'
   compile 'com.android.support:appcompat-v7:24.2.0'
   compile 'com.android.support:design:24.2.0'
   compile 'com.android.support:support-annotations:24.2.0'
   ......
   androidTestCompile 'com.android.support:support-annotations:24.2.0'
   androidTestCompile 'com.android.support.test:runner:0.5'
   androidTestCompile 'com.android.support.test:rules:0.5'
}

测试Java类

package com.tyagiabhinav.xyz;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import com.tyagiabhinav.xyz.Util.PrefHelper;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Created by abhinavtyagi on 24/08/16.
 */


@RunWith(AndroidJUnit4.class)
public class PrefTester {

    Context mMockContext;

    private PrefTester() {
        super();
    }

    @Before
    public void setUp() {
        mMockContext = InstrumentationRegistry.getTargetContext();
        PrefHelper.init(mMockContext);
    }

    @Test
    public void testSharedPref(){
        Assert.assertEquals(false,PrefHelper.isLoggedIn());
    }

}

3 个答案:

答案 0 :(得分:0)

您正在调试版本上运行proguard。 Proguard可以从java代码中删除类。通过在build.gradle文件中设置“minifyEnabled false”来关闭proguard

buildTypes {
    debug {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'),   'proguard-rules.pro'
    }

答案 1 :(得分:0)

做了一些改动,问题得到了解决!

测试代码
通过打开启动画面改变了获取上下文的方式

@RunWith(AndroidJUnit4.class)
public class PrefTester {

    Context mMockContext;

    @Rule
    public ActivityTestRule<SplashActivity> mActivityRule = new ActivityTestRule<>(SplashActivity.class);

    @Before
    public void setUp() {
        mMockContext = mActivityRule.getActivity().getApplicationContext();
        PrefHelper.init(mMockContext);
    }

    @Test
    public void testSharedPref(){
        Assert.assertEquals(false,PrefHelper.isLoggedIn());
    }

}

<强>的build.gradle(APP)
在debug中设置proguard false - &gt; minifyEnabled false
启用multidex - &gt; multiDexEnabled true
添加依赖 - &gt; compile 'com.android.support:multidex:1.0.1'

在发布此问题之前,我已经测试了build.gradle方法,我想我是以错误的方式获取上下文。上述变化的组合现在对我有用。

答案 2 :(得分:0)

你的proguard-rules.pro文件中有什么?您可以尝试删除它,只需使用默认的Android规则。

作为一个说明,我认为您可能想要重新评估您的依赖项。从您显示的gradle文件的片段中,您似乎不太可能只使用这些依赖项来达到64K dex限制。您是否包含更多您未在上面列出的图书馆?项目中的jar文件中是否有库? (这很容易解释方法的数量)

Multidex是一种黑客攻击 - 除非你别无选择,否则你真的不应该使用它。完全使用它会产生性能影响/等等,并且一些奇怪的问题会突然出现在哪些类中存在于哪个dex文件中。例如 - 从清单引用的任何类都必须在您的主要dex文件中结束,这可能会给您带来奇怪的约束。