Эспрессо - получить текст элемента

Если у меня есть элемент AppCompatTextView, к которому я могу получить доступ:

onView(withId(R.id.allergies_text))

От инспектора по макету:

введите описание изображения здесь

Есть ли способ получить доступ к тексту элемента в Android Studio? (чтобы получить доступ к любому тексту... не проверять, существует ли какой-либо текст в элементе)

Я пытался сделать:

val tv = onView(withId(R.id.medical_summary_text_view)) as TextView
val text = text.text.toString()
print(text)

Но я получаю ошибку:

android.support.test.espresso.ViewInteraction не может быть приведен к android.widget.TextView

2 ответа

Решение

Вы должны создать средство сопоставления для доступа к значению этого элемента.

Например, вы можете проверить, имеет ли его текст какое-то значение:

Matcher<View> hasValueEqualTo(final String content) {

    return new TypeSafeMatcher<View>() {

        @Override
        public void describeTo(Description description) {
            description.appendText("Has EditText/TextView the value:  " + content);
        }

        @Override
        public boolean matchesSafely(View view) {
            if (!(view instanceof TextView) && !(view instanceof EditText)) {
                    return false;
            }
            if (view != null) {
                String text;
                if (view instanceof TextView) {
                    text = ((TextView) view).getText().toString();
                } else {
                    text = ((EditText) view).getText().toString();
                }

                return (text.equalsIgnoreCase(content));
            }
            return false;
        }
    };
}

И назовите это так:

onView(withId(R.id.medical_summary_text_view))
    .check(matches(hasValueEqualTo(value)));

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

Matcher<View> textViewHasValue() {

    return new TypeSafeMatcher<View>() {

        @Override
        public void describeTo(Description description) {
            description.appendText("The TextView/EditText has value");
        }

        @Override
        public boolean matchesSafely(View view) {
            if (!(view instanceof TextView) && !(view instanceof EditText)) {
                    return false;
            }
            if (view != null) {
                String text;
                if (view instanceof TextView) {
                    text = ((TextView) view).getText().toString();
                } else {
                    text = ((EditText) view).getText().toString();
                }

                return (!TextUtils.isEmpty(text));
            }
            return false;
        }
    };
}

И назовите это так:

onView(withId(R.id.medical_summary_text_view))
    .check(matches(textViewHasValue()));

Вы можете получить текст ViewInteraction следующей функцией:

fun getText(matcher: ViewInteraction): String {
    var text = String()
    matcher.perform(object : ViewAction {
        override fun getConstraints(): Matcher<View> {
            return isAssignableFrom(TextView::class.java)
        }

        override fun getDescription(): String {
            return "Text of the view"
        }

        override fun perform(uiController: UiController, view: View) {
            val tv = view as TextView
            text = tv.text.toString()
        }
    })

    return text
}
val numberResult: ViewInteraction = onView(withId(R.id.txNumberResult))
var searchText = getText(numberResult)

Я столкнулся с подобной проблемой, и вот что в итоге сработало для меня:

если у вас есть правило активности

var activityRule = ActivityTestRule(MainActivity::class.java, true, false)

тогда вы можете сделать что-то вроде этого:

activityRule.launchActivity(null)
val textView: TextView = activityRule.activity.findViewById(R.id.some_text_view)
val text = textView.text

Я думаю, что это больше похоже на то, что искал оригинальный постер.

Если вы действительно хотите иметь текст, а не только сопоставить его с другим значением или пустым, я публикую полное окончательное рабочее решение на Java (не Kotlin) на основе алгоритма @Mesut GUNES.

public class TextHelpers {
public static String getText(ViewInteraction matcher){
    final String[] text = new String[1];
    ViewAction va = new ViewAction() {

        @Override
        public Matcher<View> getConstraints() {
            return isAssignableFrom(TextView.class);
        }

        @Override
        public String getDescription(){
            return "Text of the view";
        }

        @Override
        public void perform(UiController uiController,View view) {
            TextView tv = (TextView) view;
            text[0] = tv.getText().toString();
        }
    };

    matcher.perform(va);

    return text[0];
}

}

Итак, в вашем тесте вы можете назвать это так:

TextHelpers.getText(Espresso.onView(withId(R.id.element)));

Он работает для всех элементов управления, расширяющих TextView, так же как и для EditText.

Другие вопросы по тегам