Android Espresso:如何在将一个活动跟踪到多个片段架构时测试特定片段

问题描述 投票:17回答:3

我的应用程序包含一个Activity为许多Fragments

我希望使用Espresso来测试Fragments的用户界面。但是我遇到了一个问题。

我怎样才能测试Fragment中没有添加到ActivityonCreate。我在Fragments上看到的所有例子都涉及在Fragment中加入onCreate。那么我怎么能告诉Espresso去特定的Fragment并从那里开始呢?

谢谢

android android-fragments android-testing android-espresso
3个回答
-7
投票

Espresso只有在显示时才能测试Fragments。这需要他们由Activity显示。

根据您当前的设置,您必须使用Espresso以click()的方式(就像用户一样)使用您实际想要测试的Fragment

在我的一个项目中,我有一个显示ViewPagerFragments。对于那些Fragments我使用自定义FragmentTestRule隔离测试它们。我可以直接启动每个Fragment并使用Espresso进行测试。见this answer

你也可以:

  • 不要使用FragmentsActivities更容易测试。你可以自己测试每个Activity。在大多数情况下,Fragments没有优于ActivitiesFragments只是让实施和测试更加困难。
  • 使FragmentActivity在创建时直接显示某个Fragment。例如。为您的FragmentActivity提供额外的特殊意图。但这会为您的应用添加测试代码,这通常不是一个好的解决方案。

2
投票

如果您正在使用导航架构组件,则可以在测试开始时通过深度链接到目标片段(使用适当的参数)立即测试每个片段。

@Rule
@JvmField
var activityRule = ActivityTestRule(MainActivity::class.java)

protected fun launchFragment(destinationId: Int,
                             argBundle: Bundle? = null) {
    val launchFragmentIntent = buildLaunchFragmentIntent(destinationId, argBundle)
    activityRule.launchActivity(launchFragmentIntent)
}

private fun buildLaunchFragmentIntent(destinationId: Int, argBundle: Bundle?): Intent =
        NavDeepLinkBuilder(InstrumentationRegistry.getInstrumentation().targetContext)
                .setGraph(R.navigation.navigation)
                .setComponentName(MainActivity::class.java)
                .setDestination(destinationId)
                .setArguments(argBundle)
                .createTaskStackBuilder().intents[0]

destinationId是导航图中的片段目标ID。以下是一旦您准备好启动片段就会执行的调用示例:

launchFragment(R.id.target_fragment, targetBundle())

private fun targetBundle(): Bundle? {
    val bundle = Bundle()
    bundle.putString(ARGUMENT_ID, "Argument needed by fragment")
    return bundle
}

这里也有更详细的回答:https://stackoverflow.com/a/55203154/2125351


-1
投票

只需使用Activity的SupportFragmentManager显示片段即可。

例如(Kotlin)与ActivityTestRule:

@Rule
@JvmField
var activityRule = ActivityTestRule(MainActivity::class.java)

在测试之前这样做:

@Before
fun setup() {
    activityRule.activity.supportFragmentManager.beginTransaction().replace(R.id.main_activity_container_for_your_fragments, FragmentToShow(), "fragment-tag").commitAllowingStateLoss()
    Thread.sleep(500)
}
© www.soinside.com 2019 - 2024. All rights reserved.