2

I was doing black box testing using Espresso. I followed the guide from another thread (Android Espresso how to write tests using apk?). But my test can't find class on DexPathList. The error message is:

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.twitter.android.DispatchActivity" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/...test-2.apk", zip file "/data/app/...-2.apk"],nativeLibraryDirectories=[/data/app-lib/....test-2, /data/app-lib/...-2, /vendor/lib, /system/lib]]

The app I am testing is Twitter and I don't have the source code. So I created an android project in Android Studio.

The manifest file looks like:

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="my.test">

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:theme="@style/AppTheme">

    </application>

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.twitter.android">
    </instrumentation>
</manifest>

The test class:

@RunWith(AndroidJUnit4.class)
public class Replayer {
    private static final String CLASSNAME = "com.twitter.android.DispatchActivity";

    private static Class<? extends Activity> activityClass;
    static {
        try {
            activityClass = (Class<? extends Activity>) Class.forName(CLASSNAME);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    @Rule
    public final ActivityTestRule<?> activityRule
            = new ActivityTestRule<>(activityClass);

    @Test
    public void launchMain() {
        Espresso.onView(ViewMatchers.withText("Log in")).perform(ViewActions.click());
    }
}

I didn't see the target app on DexPathList. Did I misconfigure my project?

Community
  • 1
  • 1
Halo
  • 31
  • 6

1 Answers1

1

Well, I figured it out after almost one month exploring... The target application needs to be specified in build.gradle file, like this:

android {
    ....
    defaultConfig {
        ...
        applicationId "com.twitter.android"
    }
    ...
}

The gradle will automatically generate the instrumentation node in android manifest file. Note that manually adding android:targetPackage in the manifest won't work.

Halo
  • 31
  • 6
  • According to the [DSL reference](http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.ProductFlavor.html#com.android.build.gradle.internal.dsl.ProductFlavor:testApplicationId), `testApplicationId` means "Test application ID" and is irrelevant to the package name of the application under test. – Jeremy Kao Feb 04 '16 at 07:07
  • In addition, [User Guide](http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Testing) says: The value of the `targetPackage` attribute of the `instrumentation` node in the test application manifest is automatically filled with the package name of the tested app, even if it is customized through the `defaultConfig` and/or the Build Type objects. This is one of the reason this part of the manifest is generated automatically. – Jeremy Kao Feb 04 '16 at 07:13
  • @JeremyKao Thanks so much for pointing it out. It's actually a typo, and it should be applicationId instead of testApplicatoinId. – Halo Feb 08 '16 at 17:29