Espresso - 在列表视图中按文本点击
Posted
技术标签:
【中文标题】Espresso - 在列表视图中按文本点击【英文标题】:Espresso - Click by text in List view 【发布时间】:2014-04-09 14:34:05 【问题描述】:我正在尝试使用 Espresso 在列表视图中单击文本。我知道他们有this guide,但我不知道如何通过查找文本来完成这项工作。这是我尝试过的
Espresso.onData(Matchers.allOf(Matchers.is(Matchers.instanceOf(ListView.class)), Matchers.hasToString(Matchers.startsWith("ASDF")))).perform(ViewActions.click());
正如预期的那样,这不起作用。该错误表示层次结构中没有视图。有谁知道如何选择字符串? (在这种情况下为"ASDF"
)提前致谢。
由于@haffax而更新
我收到错误:
com.google.android.apps.common.testing.ui.espresso.AmbiguousViewMatcherException: 'is assignable from class: class android.widget.AdapterView' 匹配层次结构中的多个视图。
第二个错误
使用此代码
onData(hasToString(startsWith("ASDF"))).inAdapterView(withContentDescription("MapList")).perform(click());
我收到此错误
com.google.android.apps.common.testing.ui.espresso.PerformException:在视图上执行“加载适配器数据”时出错,内容描述为“MapList”。
原因:java.lang.RuntimeException:找不到匹配的数据:asString(以“ASDF”开头的字符串)
解决方案
onData(anything()).inAdapterView(withContentDescription("desc")).atPosition(x).perform(click())
【问题讨论】:
这个异常的有趣之处在堆栈跟踪的下方。整个堆栈跟踪中应该有一个“Caused by:”部分。这描述了真正出了什么问题。请分享完整的堆栈跟踪以供分析。 @haffax,检查一下。那个字符串肯定在那里。 @haffax,但是,首先有一个线性布局。 这变得越来越复杂。那么,您实际上无法访问适应的类型,这是正确的吗? 如果您无权访问支持数据类型,那么您需要使用 onData(anything()).inAdapterView(...) 遍历该项目在 ListView 中的位置.atPosition(x).perform(click()) 点击列表中的第 x 个项目。 【参考方案1】:问题是,您尝试将列表视图本身与instanceOf(ListView.class)
匹配作为onData()
的参数。 onData()
需要一个数据匹配器来匹配ListView
的适配数据,而不是ListView
本身,也不是Adapter.getView()
返回的View
,而是实际数据。
如果你的生产代码中有这样的东西:
ListView listView = (ListView)findViewById(R.id.myListView);
ArrayAdapter<MyDataClass> adapter = getAdapterFromSomewhere();
listView.setAdapter(adapter);
那么 Espresso.onData()
的 Matcher 参数应该匹配 MyDataClass
的所需实例。
所以,这样的事情应该可以工作:
onData(hasToString(startsWith("ASDF"))).perform(click());
(您可以使用org.hamcrest.Matchers
的方法使用另一个Matcher)
如果您的活动中有多个适配器视图,您可以使用视图匹配器调用 ViewMatchers.inAdapterView()
,指定 AdapterView,如下所示:
onData(hasToString(startsWith("ASDF")))
.inAdapterView(withId(R.id.myListView))
.perform(click());
【讨论】:
答案扩展为包括层次结构中多个 AdapterViews 的解决方案。 我遇到了同样的错误,但**MATCHES**
的错误更少
匹配的两个,似乎是一样的。我能看到的唯一区别是is=focused=false
好吧,您必须自己整理匹配项。有这么多具有相同 ID 的不同列表视图似乎很奇怪。你不能给你的列表视图不同的ID吗?或者这是因为在 ListFragments 中使用了?其他进一步区分的方法:为视图分配标签并使用 hasTag() 匹配器或使用 isDescendantOfA() 通过层次结构进行区分。
是的,我也觉得很奇怪。我没有编写应用程序,我只是测试它。但是,是的,你是对的,我不能给他们不同的 id,因为他们在 ListFragments 中。我会考虑添加一个标签。【参考方案2】:
如果适配器有自定义模型类,例如Item
:
public static Matcher<Object> withItemValue(final String value)
return new BoundedMatcher<Object, Item>(Item.class)
@Override
public void describeTo(Description description)
description.appendText("has value " + value);
@Override
public boolean matchesSafely(Item item)
return item.getName().toUpperCase().equals(String.valueOf(value));
;
然后调用以下:
onData(withItemValue("DRINK1")).inAdapterView(withId(R.id.menu_item_grid)).perform(click());
【讨论】:
这在一个屏幕上对我有用,但在另一个屏幕上,Espresso 似乎滚动到该项目,但即使调用 perform(click()) 也不会单击该项目(用断点测试过)....这很奇怪【参考方案3】:onData(hasEntry(equalTo(ListViewActivity.ROW_TEXT),is("List item: 25")))
.onChildView(withId(R.id.rowTextView)).perform(click());
这对我来说最适合使用行文本数据..
【讨论】:
以上是关于Espresso - 在列表视图中按文本点击的主要内容,如果未能解决你的问题,请参考以下文章
Espresso 如何点击一个 ImageView 放置在 listview 的第一项?
用于 viewpager 列表视图的 Espresso 2.0 AmbiguousViewMatcherException