浓缩咖啡 - 获取元素文本

8
如果我有一个“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
4个回答

7
您需要创建一个匹配器来访问该元素的值。
例如,您可以检查它的文本是否有一些值:
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()));

1
一个很好的自定义匹配器示例。谢谢。 - speedynomads
虽然这通常是浓缩咖啡测试的工作方式,但它并没有回答用户的问题。他想找出实际匹配元素上的文本,而不是将其与已知数量进行比较。 - Shroud
但是测试的目的在于检查您的应用程序的状态和值是否与您期望的相匹配。对我来说,获取值是调试应用程序,而不是测试它。每个测试中重要的是检查您期望的条件是否发生。 - jeprubio

5
您可以通过以下函数获取 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)

0

我曾经遇到过类似的问题,以下是最终解决方案:

如果你有一个活动规则

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

我认为这可能更符合原帖作者的需求。


我尝试了您的示例,但是出现了异常:IllegalStateException: searchActivity.activity.…ewById(R.id.recipe_title) must not be null 我无法以这种方式获取文本。 - Ilya G

0

当你真正想要获取文本而不仅仅是与另一个值或空值匹配时,我将发布基于 @Mesut GUNES 算法的Java(不是Kotlin)完整的最终工作解决方案。

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。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接