3

I am trying to run Espresso tests for an Android app. It works fine on a hardware device. When I run it on a freshly created AVD emulator it fails as shown here:

:ExampleApp:connectedDebugAndroidTest

com.example.MainFragmentTest > initializationError[Nexus_5_API_19(AVD) - 4.4.2] 
FAILED 
    java.lang.NoClassDefFoundError: com/example/MainActivity
    at java.lang.Class.getDeclaredFields(Native Method)
:ExampleApp:connectedDebugAndroidTest FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':ExampleApp:connectedDebugAndroidTest'.
> There were failing tests. See the report at: 
file:///home/user/work/ExampleApp/build/reports/androidTests/connected/index.html

The HTML report contains the following stacktrace:

java.lang.NoClassDefFoundError: com/example/MainActivity
at java.lang.Class.getDeclaredFields(Native Method)
at java.lang.Class.getDeclaredFields(Class.java:610)
at org.junit.runners.model.TestClass.getSortedDeclaredFields(TestClass.java:77)
at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:70)
at org.junit.runners.model.TestClass.<init>(TestClass.java:57)
at org.junit.runners.ParentRunner.createTestClass(ParentRunner.java:88)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:83)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at android.support.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.java:38)
at android.support.test.runner.AndroidJUnit4.<init>(AndroidJUnit4.java:36)
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.buildAndroidRunner(AndroidAnnotatedBuilder.java:57)
at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.runnerForClass(AndroidAnnotatedBuilder.java:45)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runner.Computer.getRunner(Computer.java:40)
at org.junit.runner.Computer$1.runnerForClass(Computer.java:31)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:101)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:87)
at org.junit.runners.Suite.<init>(Suite.java:81)
at org.junit.runner.Computer.getSuite(Computer.java:28)
at android.support.test.internal.runner.TestRequestBuilder.classes(TestRequestBuilder.java:701)
at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:664)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:329)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:226)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)

Caused by: java.lang.ClassNotFoundException: Didn't find class 
  "com.example.MainActivity" on path: DexPathList[[zip file 
  "/system/framework/android.test.runner.jar", zip file 
  "/data/app/com.example.debug.test-1.apk", zip file 
  "/data/app/com.example.debug-1.apk"],
  nativeLibraryDirectories=[/data/app-lib/com.example.debug.test-1, 
  /data/app-lib/com.example.debug-1, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
... 28 more

I am basically following the structure in espresso/BasicSample/ChangeTextBehaviorTest.java. This test works on the emulator!

For my test I could boil it down that running the test already fails when I just use the following code:

@RunWith(AndroidJUnit4.class)
public class MainFragmentTest {

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

Here is the complete test class:

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

import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;

import com.example.R;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

@RunWith(AndroidJUnit4.class)
public class MainFragmentTest {

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

    MainActivity mMainActivity;

    MainFragment mMainFragment;

    @Before
    public void setUp() {
        mMainActivity = mActivityRule.getActivity();
        mMainFragment = (MainFragment) mMainActivity
                .getSupportFragmentManager()
                .findFragmentByTag(MainFragment.FRAGMENT_TAG);
    }

    @Test
    public void testHeadline() {
        onView(withId(R.id.headline)).check(matches(withText(R.string.headline)));
    }
}

I am currently using the following tool chain:

  • com.android.tools.build:gradle:1.4.0-beta2
  • buildToolsVersion "23.0.1"
  • compileSdkVersion 22
  • targetSdkVersion 22
  • Gradle wrapper 2.5
  • java version "1.7.0_79" OpenJDK
JJD
  • 50,076
  • 60
  • 203
  • 339

3 Answers3

5

After some trial and error, I got mine running with this tweak:

androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.1'

change to

androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2') {
    exclude group: 'com.android.support', module: 'support-v4'
}

Somehow there are things included in espresso-contrib that prevented the correct version of support-v4 from being included in the test package, and caused the class loader to fail.

Yenchi
  • 2,076
  • 24
  • 30
  • Thank you, but I do not include `espresso-contrib` at all. Nonetheless, I checked if `espresso-core` depends on `support-v4`; it does not. – JJD Sep 17 '15 at 09:54
  • 1
    @JJD it is hard to exactly pin-point the library that caused the issue. Using resolution strategy and force the whole build to use the correct library is probably the best approach. See http://stackoverflow.com/a/29859202/133616 – Yenchi Sep 17 '15 at 16:10
  • 2
    Thanks for the link. I use the [Gradle View plugin](https://plugins.jetbrains.com/plugin/7150?pr=idea) to inspect the dependency tree. – JJD Sep 17 '15 at 20:16
  • @JJD Didn't know there such a tool for IntelliJ, thanks for the link!! – Yenchi Sep 18 '15 at 14:43
2

After some trial and error I realized that the error occurs with specific AVD emulators while test execute successful on others. An important side note I did not mention in the question is that the application I run the tests with uses Google Play Services. Therefore, I need to pick the emulators which supply the framework.

Tests run successful on:

  • Android 6.0 (API 23) Google APIs Intel x86 Atom System Image
  • Android 5.1.1 (API 22) Google APIs Intel x86 Atom System Image

Test do fail on:

  • Android 4.4.2 (API 19) Google APIs (x86 System Image)

Unknown / other error:

  • Android 5.1.1 (API 22) Google APIs Intel x86 Atom_64 System Image
    I cannot install the APK on this AVD due to the error described in issue #180674.
JJD
  • 50,076
  • 60
  • 203
  • 339
2

As workaround for the installation problem you can also run the instrumentation manually:

1. Generate target & test apk

gradle connectedAndroidTest

It will fail installing the apk, but still generates them as output.

2. Install test & target apk manually

adb install XXX-debug-androidTest-unaligned.apk

adb install XXX-debug.apk

3. Trigger intrumentation manually

adb shell am instrument -w -e your.package.test/.common.Instrumentation

This will show you all installed instrumentations:

adb shell pm list instrumentation

For more information have a look at the official instrumentation documentation.

Tobi
  • 166
  • 1
  • 3