使用android espresso访问自定义expandablelist中的子级 [英] accessing children in custom expandablelist using android espresso
问题描述
我正在尝试访问自定义可扩展列表中的子级.列表看起来像这样:
I am trying to access the children in my custom expandablelist. The list looks like this :
我可以使用:
Espresso.onView(allOf(withId(R.id.groupRowTextView1), withText(startsWith("Candida")))).perform(click());
当我尝试访问子EditText时:
When I try to access the child EditText like :
Espresso.onData(is(instanceOf(CustomExpandableListAdapter.class)))
.inAdapterView(withId(R.id.aversionsListView))
.onChildView(allOf(withId(R.id.childEditText), isDisplayed()))
.atPosition(1)
.perform(click());
我收到此错误:
11-30 16:47:45.733 2479-2492/com.foodaversions.people I/TestRunner﹕ ----- begin exception -----
11-30 16:47:45.733 2479-2492/com.foodaversions.people I/TestRunner﹕ com.google.android.apps.common.testing.ui.espresso.PerformException: Error performing 'load adapter data' on view 'with id: is <2131099682>'.
at com.google.android.apps.common.testing.ui.espresso.PerformException$Builder.build(PerformException.java:67)
at com.google.android.apps.common.testing.ui.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:57)
at com.google.android.apps.common.testing.ui.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:40)
at com.google.android.apps.common.testing.ui.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:159)
at com.google.android.apps.common.testing.ui.espresso.ViewInteraction.doPerform(ViewInteraction.java:90)
at com.google.android.apps.common.testing.ui.espresso.ViewInteraction.perform(ViewInteraction.java:73)
at com.google.android.apps.common.testing.ui.espresso.DataInteraction.load(DataInteraction.java:135)
at com.google.android.apps.common.testing.ui.espresso.DataInteraction.perform(DataInteraction.java:112)
at com.foodaversions.people.ModifyAversionsTest.selectGlutenIntolerance(ModifyAversionsTest.java:49)
at com.foodaversions.people.ModifyAversionsTest.test(ModifyAversionsTest.java:20)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:115)
at junit.framework.TestResult.runProtected(TestResult.java:133)
at junit.framework.TestResult.run(TestResult.java:118)
at junit.framework.TestCase.run(TestCase.java:124)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:190)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:175)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner.onStart(GoogleInstrumentationTestRunner.java:167)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1584)
Caused by: java.lang.RuntimeException: No data found matching: is an instance of com.foodaversions.people.adapters.CustomExpandableListAdapter contained values: <[Data: GroupStruct{id=6, name='Alcohol Intolerance', sourceTable=AVERSION_NAME, modifierEnum=EDITABLE, childData=
ChildStruct{id=-1, name='<Add Ingredient>', sourceTable=null, joinTable=null, modifierEnum=ADD_TEXT_VIEW}
}
(class: class com.foodaversions.people.data.ExpandableGroupData$GroupStruct) token: 0, Data: GroupStruct{id=8, name='Candida', sourceTable=AVERSION_NAME, modifierEnum=EDITABLE, childData=
ChildStruct{id=13, name='Sugar', sourceTable=AVERSION, joinTable=null, modifierEnum=DELETE}
ChildStruct{id=-1, name='<Add Ingredient>', sourceTable=null, joinTable=null, modifierEnum=ADD_TEXT_VIEW}
}
(class: class com.foodaversions.people.data.ExpandableGroupData$GroupStruct) token: 1, Data: ChildStruct{id=13, name='Sugar', sourceTable=AVERSION, joinTable=null, modifierEnum=DELETE} (class: class com.foodaversions.people.data.ChildStruct) token: 2, Data: ChildStruct{id=-1, name='<Add Ingredient>', sourceTable=null, joinTable=null, modifierEnum=ADD_TEXT_VIEW} (class: class com.foodaversions.people.data.ChildStruct) token: 3, Data: GroupStruct{id=3, name='Dairy Intolerance', sourceTable=AVERSION_NAME, modifierEnum=EDITABLE, childData=
ChildStruct{id=-1, name='<Add Ingredient>', sourceTable=null, joinTable=null, modifierEnum=ADD_TEXT_VIEW}
}
(class: class com.foodaversions.people.data.ExpandableGroupData$GroupStruct) token: 4, Data: GroupStruct{id=10, name='Egg Allergy', sourceTable=AVERSION_NAME, modifierEnum=EDITABLE, childData=
ChildStruct{id=-1, name='<Add Ingredient>', sourceTable=null, joinTable=null, modifierEnum
11-30 16:47:45.733 2479-2492/com.foodaversions.people I/TestRunner﹕ ----- end exception -----
使用onData扩展组
我无法让孩子点击工作,我发现更容易确定如何首先扩展列表:
Expanding the Group using onData
I had trouble getting the child click to work, I found it easier to work out how to expand the list first :
Espresso.onData(allOf(is(instanceOf(ExpandableGroupData.GroupStruct.class)), withGroupName("Candida")))
.inAdapterView(withId(R.id.aversionsListView))
.perform(click());
我认为这可能有助于解决单击子视图的问题.
I thought it might help towards the solution for clicking the child view.
感谢@Anna提供我解决此问题所需的指导:
Thanks to @Anna for providing the direction I needed to solve this:
// aversionsListView is the id of the ExpandableListView containing the expandable list
Espresso.onData(allOf(is(instanceOf(ChildStruct.class)), withChildName("<Add Ingredient>")))
.inAdapterView(withId(R.id.aversionsListView))
.check(matches(isDisplayed()))
.perform(click());
匹配器:
public static Matcher<Object> withChildName(String name) {
checkNotNull(name);
return withChildName(equalTo(name));
}
public static Matcher<Object> withChildName(final Matcher<String> name) {
checkNotNull(name);
// ChildStruct is the Class returned by BaseExpandableListAdapter.getChild()
return new BoundedMatcher<Object, ChildStruct>(ChildStruct.class){
@Override
public boolean matchesSafely (final ChildStruct childStruct){
return name.matches(childStruct.name);
}
@Override
public void describeTo (Description description){
name.describeTo(description);
}
} ;
}
推荐答案
使用适配器视图有几点. 如果它是从适配器加载数据,则无法使用简单视图,就好像Espresso不会等到加载数据一样. 如果您要使用
There are several points of using adapter views. If it is loading data from adapter you could not use simple view as if Espresso would not wait until data is loaded. If you are going to use
Espresso.onData(is(instanceOf(CustomExpandableListAdapter.class))) .inAdapterView(withId(R.id.aversionsListView))
然后它将返回AdapterListView
.如果要单击列表的第二项,则可以使用.atPosition(1)
.如果R.id.childEditText
是列表元素的类型,则必须将其与自定义匹配器进行匹配.您不能同时使用.onChildView(allOf(withId(R.id.childEditText), isDisplayed())).atPosition(1)
.
then it its will return AdapterListView
. If you want to click on the second item of list then .atPosition(1)
is fine to use. If R.id.childEditText
is the type of your list element you have to match it with custom matcher. You could not use .onChildView(allOf(withId(R.id.childEditText), isDisplayed())).atPosition(1)
together.
我建议写一个自定义匹配器.请查看此. 自定义匹配器有助于获取列表项开头的内容.您可以尝试编写类似的内容.
I am suggesting to write a custom matcher. Please look into this. Custom matchers are helping to get the list item with matching it at the beginning.You can try to write something like this.
onData(allOf(is(instanceOf(<List item class for adapter>.class)), withListItemCheck(check_value))).check(matches(isDisplayed()));
您的匹配器可以是这样的:
Your matcher can be like this one:
public static Matcher<Object> withListItemCheck(final <Type> check_value) {
checkNotNull(check_value);
return new BoundedMatcher<Object, <List_Item_class>>(<List_Item_class>.class) {
private String m_message = "";
@Override
public void describeTo(Description d) {
d.appendText(m_message);
}
@Override
public boolean matchesSafely(<List_Item_class> listItem) {
m_message = "Expected " + listItem+ " and got ";
if (listItem== null) {
m_message += "empty";
return false;
}
return <assertion to check `check_value` is corresponding to `listItem` or not>;
}
};
}
这篇关于使用android espresso访问自定义expandablelist中的子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!