Espresso测试在有多个匹配语句时失败,但通过较小的匹配语句通过

问题描述 投票:1回答:1

我有一个Instrument测试,其中包含四个match语句。四个语句中的一个在与其他三个语句一起运行时会失败,但如果它本身运行则通过。

这里是失败的测试

@Test
fun displayTypeFilteredPokemon(){
    // When - PokemonList fragment launch and filtered by specific type
    launchActivity()
    onView(withId(R.id.genAllButton)).perform(click())


    // Perform click action to do the filter on specific type
    onView(withId(R.id.menu_filter)).perform(click())
    onView(withText(R.string.label_type_electric)).perform(click())

    // Then - Verify the list is filtered by the selected type
    onView(withId(R.id.pokemon_list)).check(RecyclerViewItemCountAssertion(3))
    onView(withText("Magnemite")).check(matches(isDisplayed()))
    onView(withText("Jolteon")).check(matches(isDisplayed()))
    onView(withText("Emolga")).check(matches(isDisplayed()))
}

这是启动活动的代码:

private fun launchActivity(): ActivityScenario<PokemonListActivity>? {
    val scenario = launch(PokemonListActivity::class.java)

    scenario.onActivity {
        val intent = Intent()
        intent.putExtra("genId",0)
        it.intent = intent
    }

    return scenario
}

这是自定义匹配代码:

class RecyclerViewItemCountAssertion(private val matcher: Int) : ViewAssertion {

override fun check(view: View?, noViewFoundException: NoMatchingViewException?) {
    if(noViewFoundException != null){
        throw noViewFoundException
    }

    val recyclerView = view as RecyclerView
    val adapter = recyclerView.adapter!!

    assertThat(adapter.itemCount, IsEqual(matcher))
}

}

使用这组匹配项时,它会通过:

onView(withId(R.id.pokemon_list)).check(RecyclerViewItemCountAssertion(3))
onView(withText("Jolteon")).check(matches(isDisplayed()))
onView(withText("Emolga")).check(matches(isDisplayed()))

或当这组匹配项也通过时:

onView(withText("Magnemite")).check(matches(isDisplayed()))

这里是正在测试的视图:

enter image description here

我有些困惑,因为视图中显然有匹配的文本。可能是资源没有闲置,因此测试刚刚结束?例如,只有一个匹配器通过的测试是由于速度足够快才能在完成之前匹配?

[我曾经考虑过引入EspressoIdlingResource,但是我已经阅读过,它在代码库中引入了一些困难,我希望出于学习目的而使其简单。

我认为竞赛条件存在问题的另一个指标是,当我调试测试通过时。当我刚运行测试时,它失败。

编辑1:单独运行所有测试时,我没有任何错误。在该类中运行所有测试时,出现以下错误:

androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: com.stegner.androiddex:id/menu_filter
android kotlin match android-espresso
1个回答
0
投票

您编写浓缩咖啡测试的方法似乎是错误的。

[编写UI测试时,我们要确认的是以下内容。“如果用户交互单击按钮X,然后滑动页面,将500写入此编辑文本,然后单击按钮Y,则他将能够看到文本Z”。如您所见,我们正在测试应用程序,就好像我们是最终用户一样,只需与屏幕上看到的元素进行交互。

private fun launchActivity(): ActivityScenario<PokemonListActivity>? {
    val scenario = launch(PokemonListActivity::class.java)

    scenario.onActivity {
        val intent = Intent()
        intent.putExtra("genId",0)
        it.intent = intent
    }

    return scenario
}

[当您使用launchActivity并通过意图传递数据时,您无视我们要测试的内容,最终用户无法通过意图传递数据,他们只是单击一个按钮,该按钮触发我们的代码以意图传递数据。因此,一个很好的测试应该是从头到尾(从启动屏幕到您想要的屏幕),并且模仿用户的动作(单击X,单击Y,将500写入Z等)现在,您的问题很可能是由于在方法中的每个测试中都使用了launchActivity导致的,第二个测试无法启动Activity(至少它不能足够快地启动活动),因此您会遇到错误第一个断言。

androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: com.stegner.androiddex:id/menu_filter

您应从测试方法中删除launchActivity(),并使用应用程序显示的第一个屏幕定义活动测试规则。

  @Rule
  public ActivityTestRule<MyFirstActivity> activityRule =
      new ActivityTestRule<>(MyFirstActivity.class);

当您使用注解Rule为此类注解时,在每次测试开始之前,请确保已加载此活动,然后您可以通过模拟用户交互进入想要的页面。如果您在应用此解决方案后仍然遇到问题,请以注释的形式写出来,因为这样您的问题将与同步相关,需要不同的答案。

© www.soinside.com 2019 - 2024. All rights reserved.