Noclassdeffounderror when implementing Espresso Idlingresource

Asked

Viewed 55 times

3

I need to warn [Espresso][1] to wait until my Activity is idle. For this I am using the interface IdlingResource. 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;
        }
    }

Espresso automatically waits for an Asynctask to finish, meaning if I use Ansyctask I don’t 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 apenar on my cell phone (Motorola XT1058 or Moto X) If I run exactly the same test on the Emulator (Genymotion) or any other device, 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 the code my test:

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
  • Exception, could you tell me which line is 16 on your ApplicationTest? How are you doing regarding classpath? It seems that when running the test in the emulator, the MainActivity is not in the same classpath as your test.

  • @Wakim It’s the call to the builder super(MyActivity.class).

  • And how is the classpath? Could you include an image of the Project tree? Another question, using Gradle or Ant?

  • @Wakim I’m using Android Studio and Gradle. Classes are on the same classpath, believe me. Thanks for the help.

  • @Exceptional you can put the contents of Gradle.build?

  • @Igorcastañedaferreira made!

Show 1 more comment

1 answer

4


The problem lies in its configuration of Gradle. But precisely in the section:

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

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

For your Compile project, simply remove the espresso dependency instruction in the test project.

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.