使用android espresso访问自定义expandablelist中的子级 [英] accessing children in custom expandablelist using android espresso

查看:49
本文介绍了使用android espresso访问自定义expandablelist中的子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试访问自定义可扩展列表中的子级.列表看起来像这样:

I am trying to access the children in my custom expandablelist. The list looks like this :

自定义ExpandableList

我可以使用:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆