Эспрессо-тест не пройден, когда несколько операторов соответствия, но проходит с меньшими операторами соответствия - PullRequest
1 голос
/ 17 января 2020

У меня есть тест инструмента, в котором есть четыре выражения соответствия. Есть одно из четырех утверждений, которое не выполняется при запуске с тремя другими, но проходит, если оно выполняется само по себе.

вот тест, который не прошел

@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

1 Ответ

1 голос
/ 03 февраля 2020

Ваш подход к написанию эспрессо-тестов кажется неправильным.

При написании теста пользовательского интерфейса мы хотим подтвердить следующее. «Если пользователь нажмет кнопку 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 и c). Теперь ваша проблема, скорее всего, связана с использованием 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);

Когда вы аннотируете этот класс аннотацией Правило , перед началом каждого теста он будет проверять, загружено ли это действие, и затем вы можете go перейти на нужную страницу, имитируя взаимодействие с пользователем. Если после применения этого решения у вас все еще есть проблемы, пожалуйста, напишите это как комментарий, потому что тогда ваша проблема будет связана с синхронизацией, которая требует другого ответа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...