android之NoClassDefFoundError 实现 IdlingResource

sxdcgaq8080 阅读:137 2025-02-15 21:57:57 评论:0

我需要告诉 Espresso 等到我的 Activity 空闲。我正在使用界面IdlingResource为达到这个。这是我用于测试的代码:

    public class MyActivity extends Activity implements IdlingResource { 
 
        private boolean isIdle; 
        ResourceCallback resourceCallback; 
 
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.activity_my); 
 
            final Button myButton = (Button) findViewById(R.id.myButton); 
            final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); 
 
            new Handler().postDelayed(new Runnable() { 
                @Override 
                public void run() { 
                    myButton.setVisibility(View.VISIBLE); 
                    progressBar.setVisibility(View.GONE); 
                    isIdle = true; 
                } 
            }, 3000); 
        } 
 
        public void ButtonClicked(View view) { 
            Toast.makeText(MyActivity.this, "OK", Toast.LENGTH_SHORT).show(); 
        } 
 
        @Override 
        public String getName() { 
            return getClass().getName(); 
        } 
 
        @Override 
        public boolean isIdleNow() { 
 
            if(isIdle){ 
                resourceCallback.onTransitionToIdle(); 
                return true; 
            } 
 
            return false; 
        } 
 
        @Override 
        public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { 
            this.resourceCallback = resourceCallback; 
        } 
    } 

Espresso 自动等待 AsyncTask 完成,所以如果我使用 AnsycTask,我什至不需要实现这个接口(interface)。问题是我正在使用一个库与网络通信,它似乎没有使用 AnsyncTasks 或 Espresso 不知道这一点。

我的问题是上面的代码工作正常 仅在我的设备上 (摩托罗拉 XT1058 或 Moto X)如果我在模拟器(Genymotion)或任何其他设备上运行相同的测试,我最终会遇到以下异常:
junit.framework.AssertionFailedError: Exception in constructor: testA (java.lang.NoClassDefFoundError: rapnaveia.com.br.myapplication.MyActivity 
at rapnaveia.com.br.myapplication.ApplicationTest.<init>(ApplicationTest.java:16) 
at java.lang.reflect.Constructor.constructNative(Native Method) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:417) 
at junit.runner.BaseTestRunner.getTest(BaseTestRunner.java:118) 
at android.test.AndroidTestRunner.getTest(AndroidTestRunner.java:149) 
at android.test.AndroidTestRunner.setTestClassName(AndroidTestRunner.java:57) 
at android.test.suitebuilder.TestSuiteBuilder.addTestClassByName(TestSuiteBuilder.java:80) 
at android.test.InstrumentationTestRunner.parseTestClass(InstrumentationTestRunner.java:443) 
at android.test.InstrumentationTestRunner.parseTestClasses(InstrumentationTestRunner.java:424) 
at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:370) 
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner.onCreate(GoogleInstrumentationTestRunner.java:114) 
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4435) 
at android.app.ActivityThread.access$1300(ActivityThread.java:141) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:137) 
at android.app.ActivityThread.main(ActivityThread.java:5103) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
at dalvik.system.NativeStart.main(Native Method) 
) 
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191) 
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176) 
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554) 
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner.onStart(GoogleInstrumentationTestRunner.java:167) 
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701) 

这里是我的测试类的代码:
public class ApplicationTest extends ActivityInstrumentationTestCase2<MyActivity> { 
 
    public ApplicationTest() { 
        super(MyActivity.class); 
    } 
 
    public void testA(){ 
        Espresso.registerIdlingResources(getActivity()); 
        Espresso.onView(withId(R.id.myButton)).perform(click()); 
    } 
} 

构建.gradle
apply plugin: 'com.android.application' 
 
android { 
    compileSdkVersion 20 
    buildToolsVersion "20.0.0" 
 
    defaultConfig { 
        applicationId "rapnaveia.com.br.myapplication" 
        minSdkVersion 15 
        targetSdkVersion 20 
        versionCode 1 
        versionName "1.0" 
 
        testApplicationId 'br.com.rapnaveia' 
        testInstrumentationRunner 'com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner' 
    } 
    buildTypes { 
        release { 
            runProguard false 
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
        } 
    } 
} 
 
dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    androidTestCompile files('libs/espresso-1.1-bundled.jar') 
} 

请您参考如下方法:

问题出在 gradle 配置中。您的项目正在尝试编译 espresso jar 两次。

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    androidTestCompile files('libs/espresso-1.1-bundled.jar') 
} 

使用此配置,espresso jar 由您的主项目和您的测试项目编译。因此,当您尝试执行测试时,主项目无法正确构建,从而导致错误(而且我认为您可以在设备中运行测试很奇怪)。

要运行测试,您所要做的就是从测试目标的依赖项中删除编译指令。
dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
} 

android 测试项目将使用在主项目中编译的 espresso jar,因为主项目已“编译”到测试项目中。


标签:Android
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号