user1596371
user1596371

Reputation:

Android/Gradle espresso test not starting activity

I'm having difficulty convincing the new Android build system to run tests. When running the test it gives the Unable to resolve activity for: Intent error which has been discussed in other questions but there is nothing in there which have fixed my problem.

I've stripped it down so that my test package does not rely on my main package (com.wealdtech.app) at all but still have the problem starting activity.

My test activity:

package com.wealdtech.test;

import android.app.Activity;
import android.os.Bundle;

public class TileLayoutTestActivity extends Activity
{
  @Override
  public void onCreate(final Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
  }
}

And my test class:

package com.wealdtech.test;

import android.test.ActivityInstrumentationTestCase2;

public class TileLayoutTest extends ActivityInstrumentationTestCase2<TileLayoutTestActivity>
{
  public TileLayoutTest()
  {
    super(TileLayoutTestActivity.class);
  }

  @Override
  protected void setUp() throws Exception
  {
    super.setUp();
    setActivityInitialTouchMode(false);
  }

  public void testNull()
  {
    final TileLayoutTestActivity activity = getActivity();
    activity.finish();
  }

Relevant parts of build.gradle:

apply plugin: 'android-library'

android {
  compileSdkVersion 19
  buildToolsVersion "19.0.3"

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
  }

  defaultConfig {
    minSdkVersion 11
    targetSdkVersion 19

    testPackageName "com.wealdtech.test"
    testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
  }
}

The full stack trace I obtain is:

java.lang.RuntimeException: Could not launch activity
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentation.startActivitySync(GoogleInstrumentation.java:286)
at android.test.InstrumentationTestCase.launchActivityWithIntent(InstrumentationTestCase.java:119)
at android.test.InstrumentationTestCase.launchActivity(InstrumentationTestCase.java:97)
at android.test.ActivityInstrumentationTestCase2.getActivity(ActivityInstrumentationTestCase2.java:104)
at com.wealdtech.test.TileLayoutTest.testNull(TileLayoutTest.java:21)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
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)
Caused by: java.lang.RuntimeException: Unable to resolve activity for: Intent { act=android.intent.action.MAIN flg=0x14000000 cmp=com.wealdtech.test/.TileLayoutTestActivity }
at android.app.Instrumentation.startActivitySync(Instrumentation.java:379)
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentation.access$101(GoogleInstrumentation.java:52)
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentation$2.call(GoogleInstrumentation.java:268)
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentation$2.call(GoogleInstrumentation.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

I haven't included my AndroidManifest.xml because everything I read suggests that I do not need to add an intent for TileLayoutTestActivity, however I have tried to do this anyway and ended up with the same result.

I have also tried changing the Gradle plugin from android-library to android in case that was causing the problem, but again the same result.

I can't see any documentation regarding prerequisites for Espresso testing, or testing with the Gradle build system, which I haven't already covered. Any ideas as to which I cannot start the activity as part of the test?

Upvotes: 10

Views: 8724

Answers (4)

rakesh rajput
rakesh rajput

Reputation: 626

Kindly change activity name inside Rule that u can able to run

ActivityTestRule mActivityRule = new ActivityTestRule<>( change activity name)

Upvotes: 1

sergej shafarenka
sergej shafarenka

Reputation: 20406

For instrumentation tests Android builds two APK's - one with the app and one with the tests. If you put activity to androidTest flavour, then it belongs to the test APK. If you start an activity using instrumentation (either directly or by using ActivityTestRule) later on, then Android searches for it in your app APK and fails, because there is no such activity in the app APK.

To solve the problem you can define a test activity (class and manifest) in the debug flavour of your app. Then it will be packed with your app APK and tests will work just fine.

Update: or - as Austyn Mahoney suggested - you should use InstrumentationRegistry.getInstrumentation().getTargetContex‌​t() to access the app context instead of instrumentation one.

Upvotes: 3

Ewoks
Ewoks

Reputation: 12435

Reference for others who can come to this post as I came, so they don't lose the time.

  1. change from legacy, abandoned, ugly ActivityInstrumentationTestCase2 to annotations which is supported by AndroidStudio, Gradle and Espresso 2. This will be developed by Google further.

  2. forget about that ActivityInstrumentationTestCase2 forever!

  3. start using @RunWith, @LargeTest, @Test, @Rule ...

Upvotes: 3

MithrilTuxedo
MithrilTuxedo

Reputation: 548

For a project that uses the android-library plugin, it's semi-accurate to say that the AndroidManifest.xml isn't really used. In fact all a library project's manifest needs to compile is this:

<manifest package="com.package.yours"/>

Any permissions or intents you try to put in it will be ignored when the your AAR file is created. It being a library, and as near as I can tell, nothing in the library project's manifest makes it into the AAR (or JAR if you're making one of those too).

But! That is the manifest that's going to be used when you build a test project that gets pushed to a device. You can literally dump gibberish in src/androidTest/AndroidManifest.xml and gradle won't care, but you have to add your test activity to src/main/AndroidManifest.xml or else ./gradlew connectedCheck is going to throw runtime exceptions.

My project looks like this (it really does, I only changed the names):

src/
  androidTest/
    java/
      com.package.mine/
        TestActivity.java
        VariousTests.java
  main/
    java/
      com.package.mine/
        FancyLibrary.java
    AndroidManifest.xml

And here is my AndroidManifest.xml:

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

    <uses-permission android:name="android.permission.PERM_I_NEED"/>

    <application>
        <activity android:name=".TestActivity" />
    </application>
</manifest>

Otherwise, I'm using the same test runner as you, and my build.gradle is similar enough.

Upvotes: 4

Related Questions