android - 使用android espresso访问自定义可扩展列表中的 child

标签 android expandablelistview android-espresso

我正在尝试访问我的自定义可扩展列表中的子项。该列表如下所示:

Custom ExpandableList

我可以成功访问组:

Espresso.onView(allOf(withId(R.id.groupRowTextView1), withText(startsWith("Candida")))).perform(click());

当我尝试访问子 EditText 时:

    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扩展组

我在让 child 点击工作时遇到了麻烦,我发现先弄清楚如何扩展列表会更容易:

    Espresso.onData(allOf(is(instanceOf(ExpandableGroupData.GroupStruct.class)), withGroupName("Candida")))
            .inAdapterView(withId(R.id.aversionsListView))
            .perform(click());

我认为这可能有助于解决单击 subview 的问题。


解决方案

感谢@Anna 提供了解决此问题所需的方向:

    // 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);
        }
    } ;
}

最佳答案

使用适配器 View 有几个要点。 如果它正在从适配器加载数据,您将无法使用简单 View ,因为 Espresso 不会等到数据加载完毕。 如果你打算使用

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)

我建议编写自定义匹配器。请查看this . 自定义匹配器帮助获取列表项并在开始时匹配它。你可以尝试这样写。

onData(allOf(is(instanceOf(<List item class for adapter>.class)), withListItemCheck(check_value))).check(matches(isDisplayed()));

你的匹配器可以是这样的:

  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 - 使用android espresso访问自定义可扩展列表中的 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27220612/

相关文章:

android - 在 onChildClickListener 中使用 Intent 找不到方法

java - Android 测试构建错误 : Multiple dex files define Landroid/support/test/BuildConfig

android - 适用于 iOS/Android 的 AWS 移动开发工具包中内置网络的安全性如何?

android - 无法解析目标 'android-XX'

android - 当 ExpandableListView 获得焦点时,处理子选择的正确方法是什么?

java - 带有自定义 BaseExpandableListAdapter 的嵌套 ExpandableListView

android - 测试 RecyclerView 适配器

android - 滑动直到元素在 Android Espresso 中可见

java - 如何临时存储部分数据?

java - 使用 Maven 执行 Cucumber 测试