В настоящее время я пытаюсь добавить тестирование пользовательского интерфейса Espresso в свое приложение для Android, и я хочу иметь возможность настроить таргетинг на TextInputEditText через его поле Hint, а затем щелкнуть по нему и ввести какой-либо текст. (Я знаю, что лучше настроить таргетинг на идентификаторы, но в этом случае мне нужно указать подсказку)

Вот как я пытался это сделать:

Espresso.onView(Matchers.allOf(Matchers.instanceOf(TextInputEditText::class.java),
            ViewMatchers.withHint("My Hint"))).
            perform(ViewActions.click(), ViewActions.typeText("type this"))

Однако при попытке выполнить это я получаю следующую ошибку:

android.support.test.espresso.NoMatchingViewException: в иерархии не найдено соответствий: (экземпляр android.support.design.widget.TextInputEditText и с подсказкой: "Старый пароль")

Несмотря на то, что выходные данные показывают, что иерархия действительно поддерживает это представление следующим образом:

TextInputEditText {id = 2131820762, res-name = input_data, visibility = VISIBLE, width = 1328, height = 168, has-focus = true, has-focusable = true, has-window-focus = true , is-clickable = true, is-enabled = true, is-focus = true, is-focusable = true, is-layout-requested = false, is-selected = false, root-is-layout-requested = false, имеет -input-connection = true, editor-info = [inputType = 0x80091 imeOptions = 0x8000005 privateImeOptions = null actionLabel = null actionId = 0 initialSelStart = 0 initialSelEnd = 0 initialCapsMode = 0x0 hintText = My Hint label = null packageName = null fieldId = 0 fieldName = null extras = null hintLocales = null contentMimeTypes = null], x = 0,0, y = 0,0, text =, input-type = 524433, ime-target = true, has-links = false}

Не работает ли метод ViewMatchers.withHint в Espresso или есть особый способ его использования? Почему он не может найти представление, но тогда в выводе действительно показано, что оно находится в иерархии?

2
Donal Rafferty 14 Июл 2017 в 18:25
Есть ли причина, по которой вы не можете удалить сопоставитель instanceOf () и использовать только метод withHint ()? При написании тестов Espresso я стараюсь не включать в них детали реализации, чтобы они были более гибкими по мере изменения базовой реализации. Это также важно, если вы используете библиотеки поддержки, в которых базовые классы, которые выполняют одно и то же поведение, часто различаются в зависимости от вариантов ОС.
 – 
jdonmoyer
14 Июл 2017 в 22:08
Боюсь, проблема остается прежней, если я просто использую withHint ().
 – 
Donal Rafferty
15 Июл 2017 в 19:29
Убедитесь, что отображается подсказка при открытии приложения вручную. Espresso не ищет атрибут hintText, который вы видите в своем выводе (hintText является частью информации редактора), но у вас также должен быть атрибут "hint = My Hint" (для меня он расположен между "text =" и "input-type "). Кроме того, попробуйте увидеть в отладке значение этого textView.getHint (), потому что это значение, которое ищет сопоставитель подсказок.
 – 
Crepi
20 Июл 2017 в 16:07

2 ответа

Для этого уже есть открытая ошибка. См .: https://issuetracker.google.com/issues/37139118.

1
mark w. 20 Фев 2019 в 00:43

Печать в вашем Logcat может вводить в заблуждение. Если ваш TextInputEditText является дочерним представлением TextInputLayout с включенной подсказкой, TextInputLayout установит ту же подсказку внутри себя через TextInputLayout.setHint, затем установите для подсказки TextInputEditText значение null.

Вам необходимо создать настраиваемый сопоставитель для сопоставления подсказок TextInputEditText в качестве обходного пути:

fun withHint(title: String): Matcher<View> = withHint(equalTo(title))

fun withHint(matcher: Matcher<String>): Matcher<View> = object : BoundedMatcher<View, TextInputEditText>(TextInputEditText::class.java) {
    override fun describeTo(description: Description) {
        description.appendText("with hint: ")
        matcher.describeTo(description)
    }

    override fun matchesSafely(item: TextInputEditText): Boolean {
        val parent = item.parent.parent
        return if (parent is TextInputLayout) matcher.matches(parent.hint) else matcher.matches(item.hint)
    }
}

И просто замените свой ViewMatchers.withHint("My Hint") на TextInputEditTextCustomMatchers.withHint("My Hint").

0
Aaron 18 Фев 2019 в 01:45