Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Espresso unable to resolve activity for intent - Unit testing abstract base activity

I'm brand new to Espresso and I'm trying to test a behavior in an abstract activity class in android.

Based on what I've read, the best way to do this is to create a class in the test file that extends the base class and implement whatever methods are needed to exercise the superclass behavior.

I have done this, but when I try to run it, I get the following error:

(Only the relevant stack trace line is shown with some private info redacted)

Caused by: java.lang.RuntimeException: Unable to resolve activity for: Intent { act=android.intent.action.MAIN flg=0x14000000 cmp=com.redacted.redacted/.viewcontrollers.onboarding.BaseOnboardingActivityTest$SinglePageTestOnboarder }

Some questions seemed to indicate this was because of a missing manifest entry for the Activity, but it appears as if that was an old way of doing things and is no longer needed, though I may be misinterpreting things.

How can I fix this? I don't want the activity to be a part of the actual application, since it is only usable for testing.

Here is the test class code:

@RunWith(AndroidJUnit4::class)
class BaseOnboardingActivityTest {

    @Rule @JvmField
    var onboarderActivityTestRule = ActivityTestRule<SinglePageTestOnboarder>(SinglePageTestOnboarder::class.java)

    @Test
    fun testPageNumberDotsDoNotAppearWhenOnlyOnePage() {
        val testActivity = onboarderActivityTestRule.activity

        testActivity.pagesForOnboarding = getOnboardingTestPages(1)
        testActivity.displayPages()
        onView(withId(R.id.indicator_circle)).check(doesNotExist())

        testActivity.pagesForOnboarding = getOnboardingTestPages(2)
        testActivity.displayPages()
        onView(withId(R.id.indicator_circle)).check(matches(isDisplayed()))
    }

    class SinglePageTestOnboarder : BaseOnboardingActivity() {

        lateinit var pagesForOnboarding: List<OnboarderPageData>

        fun displayPages() {
            super.showOnboardingPages(pagesForOnboarding, "test")
        }

    }

    private fun getOnboardingTestPages(numPages: Int): List<OnboarderPageData> {
        val pages = arrayListOf<OnboarderPageData>()
        for (i in 0..numPages) {
            pages.add(OnboarderPageData())
        }
        return pages
    }

}

(I've browsed similar questions and done a lot of searching, but I believe my problem is somewhat different than these questions)

EDIT: Per request, full stack trace is below:

java.lang.RuntimeException: Could not launch activity
at android.support.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:460)
at android.support.test.rule.ActivityTestRule.launchActivity(ActivityTestRule.java:354)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:525)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at android.support.test.runner.AndroidJUnit4.run(AndroidJUnit4.java:101)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2136)
Caused by: java.lang.RuntimeException: Unable to resolve activity for: Intent { act=android.intent.action.MAIN flg=0x14000000 cmp=com.redacted.redacted/.viewcontrollers.onboarding.BaseOnboardingActivityTest$SinglePageTestOnboarder }
at android.app.Instrumentation.startActivitySync(Instrumentation.java:472)
at android.app.Instrumentation.startActivitySync(Instrumentation.java:435)
at android.support.test.runner.MonitoringInstrumentation.access$101(MonitoringInstrumentation.java:96)
at android.support.test.runner.MonitoringInstrumentation$4.call(MonitoringInstrumentation.java:436)
at android.support.test.runner.MonitoringInstrumentation$4.call(MonitoringInstrumentation.java:433)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
like image 280
Bassinator Avatar asked Oct 21 '25 15:10

Bassinator


1 Answers

Some questions seemed to indicate this was because of a missing manifest entry for the Activity

That is definitely the cause of that particular error. ActivityTestRule cannot start an activity that does not appear in the manifest.

How can I fix this?

Add the activity to your androidTest edition of your manifest. This will allow it to be used in testing, but it will not be part of your actual app itself.

That doesn't seem to be working. My guess, given your symptoms, is that the activity to be tested needs to be in the APK being tested, not in the APK containing your test code.

What I know works is to have the activity reside in the debug/ source set, as I have done this on a few occasions.

So, as a peer of main and androidTest, add a debug source set. In there, have a java/ tree with your SinglePageTestOnboarder activity. Move the androidTest manifest to the debug source set, and adjust it to have the proper android:name value.

This does mean that your "test" activity will be in the app itself, but only for debug builds. Presumably you are not shipping such builds; release builds do not include what is in the debug source set. If you do not even want this class in debug, you can create a separate build type, though that will make running the tests a bit more painful.

like image 120
CommonsWare Avatar answered Oct 23 '25 04:10

CommonsWare



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!