Reputation:
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
Reputation: 626
Kindly change activity name inside Rule that u can able to run
ActivityTestRule mActivityRule = new ActivityTestRule<>( change activity name)
Upvotes: 1
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().getTargetContext()
to access the app context instead of instrumentation one.
Upvotes: 3
Reputation: 12435
Reference for others who can come to this post as I came, so they don't lose the time.
change from legacy, abandoned, ugly ActivityInstrumentationTestCase2 to annotations which is supported by AndroidStudio, Gradle and Espresso 2. This will be developed by Google further.
forget about that ActivityInstrumentationTestCase2 forever!
start using @RunWith, @LargeTest, @Test, @Rule ...
Upvotes: 3
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