Android Espresso UI测试:验证ActionPage标签文本

15

我正在尝试使用Espresso测试ActionPage的文本。 但是,当我运行Ui Automation Viewer时,我可以看到ActionPage被显示为View而不是ActionView,并且它没有TextView。

我尝试像这样检查ActionLabel文本,但它不起作用:

onView(withClassName(equalToIgnoringCase("android.support.wearable.view.ActionLabel"))).check(matches(withText("MyText")));

我有一个 ActionPage 的 id,所以我可以使用 onView(withId(R.id.actionPage)) 找到它,但是我不知道如何访问其子元素以获取 ActionLabel 的文本。我尝试编写自定义匹配器,但这也不起作用:

onView(withId(R.id.actionPage)).check(matches(withChildText("MyText")));

static Matcher<View> withChildText(final String string) {
        return new BoundedMatcher<View, View>(View.class) {
            @Override
            public boolean matchesSafely(View view) {
                ViewGroup viewGroup = ((ViewGroup) view);
                //return (((TextView) actionLabel).getText()).equals(string);
                for(int i = 0; i < view.getChildCount(); i++){
                    View child = view.getChildAt(i);
                    if (child instanceof TextView) {
                        return ((TextView) child).getText().toString().equals(string);
                    }
                }
                return false;
            }

            @Override
            public void describeTo(Description description) {
                description.appendText("with child text: " + string);
            }
        };
    }

有人可以帮我一下吗?ActionLabel本身似乎没有id,并且它不是TextView...我该如何检查其中的文本?

+------>FrameLayout{id=-1, visibility=VISIBLE, width=320, height=320, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}
|
+------->ActionPage{id=2131689620, res-name=actionPage, visibility=VISIBLE, width=320, height=320, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
+-------->ActionLabel{id=-1, visibility=VISIBLE, width=285, height=111, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=17.0, y=209.0}
|
+-------->CircularButton{id=-1, visibility=VISIBLE, width=144, height=144, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=88.0, y=65.0}

输入图片说明


能否在这些布局中的至少一个上编程添加内容描述或ID?这样会更容易捕获。 - piotrek1543
1个回答

6
你可以在 allOf 中使用 withParent
onView(
    allOf(
      withParent(withId(R.id.actionPage)),
      isAssignableFrom(ActionLabel.class)))
  .check(matches(withActionLabel(is("MyText"))));

不幸的是,ActionLabel 并没有通过 getText() 公开其文本内容,因此您需要使用反射编写自定义匹配器来替代标准的 withText() 匹配器:

private static Matcher<Object> withActionLabel(
    final Matcher<CharSequence> textMatcher) {
  return new BoundedMatcher<Object, ActionLabel>(ActionLabel.class) {
    @Override public boolean matchesSafely(ActionLabel label) {
      try {
        java.lang.reflect.Field f = label.getClass().getDeclaredField("mText");
        f.setAccessible(true);
        CharSequence text = (CharSequence) f.get(label);
        return textMatcher.matches(text);
      } catch (NoSuchFieldException e) {
        return false;
      } catch (IllegalAccessException e) {
        return false;
      }
    }
    @Override public void describeTo(Description description) {
      description.appendText("with action label: ");
      textMatcher.describeTo(description);
    }
  };
}

更多信息: http://blog.sqisland.com/2015/05/espresso-match-toolbar-title.html 请提交错误报告,请求Google添加一个公共方法ActionLabel.getText(),这样您就可以在不使用反射的情况下进行测试。

谢谢!问题在于ActionLabel不能赋值给TextView,而且ActionLabel没有公共的getText()方法。 - AlexIIP
“ActionLabel” 是你自定义的视图吗?如果是的话,你可以添加一个 getText() 方法并编写一个使用它的自定义匹配器。查看博客链接以获取一个示例自定义匹配器。 - chiuki
这不是一个普通的类,而是一个Android类。请参考http://developer.android.com/reference/android/support/wearable/view/ActionPage.html。 - AlexIIP
尝试简单地使用 onView( withParent(withId(R.id.actionPage))) .check(matches(withText("MyText"))); - piotrek1543
我已经编辑了答案,包括使用反射验证ActionLabel的自定义匹配器。 - chiuki

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