Android Espresso: How do I test a specific Fragment when following one activity to several fragment architecture

Ersen Osman picture Ersen Osman · Jul 14, 2016 · Viewed 18.7k times · Source

My app consists of one Activity for many Fragments.

I wish to use Espresso to test the UI of the Fragments. However I ran into a problem.

How can I test a Fragment which is not added to an Activity in onCreate. All examples I have seen with Fragments involve the Fragment being added in onCreate. So how can I tell Espresso to go to a specific Fragment and start from there?

Thanks

Answer

Sean Blahovici picture Sean Blahovici · Mar 17, 2019

If you are using the Navigation Architecture component, you can test each fragment instantly by Deep linking to the target fragment (with appropriate arguments) at the beginning of the test.

@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 being the fragment destination id in the navigation graph. Here is an example of a call that would be done once you are ready to launch the fragment:

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

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

Also answered in more detail here: https://stackoverflow.com/a/55203154/2125351