Espresso无法解决意图活动-对基本活动进行单元测试

时间:2018-07-29 21:36:37

标签: android unit-testing android-activity kotlin android-espresso

我是Espresso的新手,我正在尝试在android中的抽象活动类中测试行为。

根据我所读的内容,最好的方法是在测试文件中创建一个类,以扩展基类并实现实现超类行为所需的任何方法。

我已经做到了,但是当我尝试运行它时,出现以下错误:

(仅显示相关的堆栈跟踪行以及一些私有信息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 }

一些问题似乎表明这是由于缺少活动的清单条目,但似乎这是一种古老的处理方式,尽管我可能会误解,但不再需要这种方式。

我该如何解决?我不希望该活动成为实际应用程序的一部分,因为该活动仅可用于测试。

这是测试类代码:

@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
    }

}

(我浏览过类似的问题并进行了大量搜索,但我认为我的问题与这些问题有所不同)

编辑:每个请求的完整堆栈跟踪如下:

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)

2 个答案:

答案 0 :(得分:1)

  

一些问题似乎表明这是由于缺少活动的清单条目

这绝对是该特定错误的原因。 ActivityTestRule无法启动清单中未显示的活动。

  

我该如何解决?

将活动添加到清单的androidTest版中。这样可以在测试中使用它,但它不会成为您实际应用程序本身的一部分。

这似乎不起作用。考虑到您的症状,我的猜测是要测试的活动需要在要测试的APK中,而不是在包含测试代码的APK中。

知道的工作是将活动驻留在debug/来源集中,这是我几次做的。

因此,作为mainandroidTest的对等方,添加一个debug源集。在其中,您的java/活动中有一棵SinglePageTestOnboarder树。将androidTest清单移动到debug源集,并将其调整为具有正确的android:name值。

这确实意味着您的“测试”活动将在应用程序本身中,但仅适用于debug构建。大概您不是要运送这样的版本。 release构建不包括debug源集中的内容。如果您甚至都不希望在debug中使用此类,则可以创建a separate build type,尽管那样会使测试工作更加痛苦。

答案 1 :(得分:0)

就我而言,我使用的是AndroidAnnotations。当使用@EActivity时,将生成另一个类。所以我应该使用Activity +“ _”。