NoClassDefFoundError when deploying Espresso IdlingResource

3

I need to tell [Espresso] [1] to wait until my Activity is idle. For this I am using the IdlingResource interface. This is all my Activity code:

    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;
        }
    }

The Espresso automatically waits for an AsyncTask to finish to proceed, ie if I use AnsycTask I do not even need this interface. The problem is that I am using a library to communicate with the network it seems that it does not use AnsyncTasks or Espresso does not identify it.

The problem is that the code I posted above works on my cell phone (Motorola XT1058 or Moto X) if I run the exact same test on the emulator (Genymotion) or on any other device, I I end up with the following Exception:

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)

And this is my test code:

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());
    }
}

build.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')
}


  [1]: https://code.google.com/p/android-test-kit/wiki/Espresso
    
asked by anonymous 20.08.2014 / 15:19

1 answer

4

The problem is with your gradle configuration. But, precisely, in the excerpt:

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

In the way your dependencies are placed, the espresso jar is compiled in both the test project and the main project. So, when trying to run the test, the project is not compiled correctly (Inclusive, strange to have worked on your mobile).

For your project to compile, simply remove the espresso dependency statement in the test project.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

The test uses the main project as a dependency, so it will "inherit" the jar build.

    
20.08.2014 / 21:41