通过导航组件对单个活动多个片段进行UI测试

时间:2020-10-18 09:29:43

标签: unit-testing android-fragments android-architecture-navigation ui-testing

我通过使用导航组件将我的辅助项目从多个活动转换为单个活动的多个片段原则,现在我想为新片段编写UI测试。

项目的导航结构如下:

SearchActivity(navHost)
          ||
SearchFragment(list of data in recyclerview)
          ||
DetailFragment(displaying details of each item by passing UIModel parcelable data)

在进行详细活动的迁移UI测试之前,如下所示:

@get:Rule
    var activityRule: ActivityTestRule<CharacterDetailActivity> =
        ActivityTestRule(CharacterDetailFragment::class.java, false, false)


    @Test
    fun shouldDisplayErrorOnLaunchWithDefaultId() {
        val intent = Intent()
        activityRule.launchActivity(intent)
        SystemClock.sleep(2000)
        onView(withId(com.google.android.material.R.id.snackbar_text))
            .check(matches(withText("Error Loading Character")))
    }

    @Test
    fun shouldLoadDataOnLaunchWithValidCharacterId() {
        val intent = Intent().putExtra(
            CHARACTER_PARCEL_KEY,
            StarWarsCharacterUiModel(
                name = "Luke",
                birthYear = "12BBY",
                heightInCm = "234",
                heightInInches = "544",
                url = "https://swapi.py4e.com/api/people/1/"
            )
        )
        activityRule.launchActivity(intent)
        SystemClock.sleep(2000)
        onView(withId(R.id.character_details_birth_year_title_text_view)).check(matches(isDisplayed()))
    }

    @After
    override fun tearDown() {
        super.tearDown()
        activityRule.finishActivity()
    }

迁移到导航组件后,我编写了以下测试:

private lateinit var navController: TestNavHostController

    @Before
    override fun setup() {
        super.setup()
        navController = TestNavHostController(
            ApplicationProvider.getApplicationContext()
        )
        navController.setGraph(R.navigation.nav_graph)
    }

@Test
    fun shouldDisplayErrorOnLaunchWithDefaultId() {
        val scenario = launchFragmentInContainer<CharacterDetailFragment>()

        scenario.onFragment { fragment ->
            Navigation.setViewNavController(fragment.requireView(), navController)
        }

        scenario.moveToState(Lifecycle.State.STARTED)
        SystemClock.sleep(2000)
        onView(withId(com.google.android.material.R.id.snackbar_text))
            .check(matches(withText("Error Loading Character")))
    }

    @Test
    fun shouldLoadDataOnLaunchWithValidCharacterId() {
        val fragmentArgs = Bundle().apply {
            StarWarsCharacterUiModel(
                name = "Luke",
                birthYear = "12BBY",
                heightInCm = "234",
                heightInInches = "544",
                url = "https://swapi.py4e.com/api/people/1/"
            ).also {
                putParcelable("character", it)
            }
        }
        val scenario = launchFragmentInContainer<CharacterDetailFragment>(fragmentArgs)

        scenario.onFragment { fragment ->
            Navigation.setViewNavController(fragment.requireView(), navController)
        }
        scenario.moveToState(Lifecycle.State.STARTED)
        SystemClock.sleep(2000)
        onView(withId(R.id.character_details_birth_year_title_text_view)).check(matches(isDisplayed()))
    }

我遇到了错误,我想那是因为片段事务。

java.lang.RuntimeException: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

我正在努力解决这个问题,但找不到任何线索

0 个答案:

没有答案