【问题标题】:Android Espresso - Unable to click text in List View generated from AdapterAndroid Espresso - 无法单击从适配器生成的列表视图中的文本
【发布时间】:2026-01-01 12:25:02
【问题描述】:

目前我有一个具有自动完成文本视图的活动。文本视图中的数据是从数组适配器填充的,我在让我的测试用例按名称单击列表视图元素之一时遇到问题。下面是截图和代码:

// setup ingredient list widget
    mFridgeList = (ListView) findViewById(R.id.fridge_list);
    mFridgeList.setAdapter(new ArrayAdapter<String>(this,
            android.R.layout.simple_dropdown_item_1line, FridgesterDB.ingredientsList));

当用户输入文本(例如:tom)时,将出现一个选项列表,用户可以选择这些选项以确认他们的选择。

我觉得我已经尝试了一千种不同的解决方案,但我得到的最一致的错误是:

在视图上执行“加载适配器数据”时出错可从类分配:android.widget.AdapterView 类

我已经尝试使用here建议的解决方案:

onData(hasToString(startsWith("tomato"))).perform(click());

和它的不同变体都无济于事。

这是从 Espresso Recorder 生成的代码,它会导致 NoMatchingViewException:

ViewInteraction appCompatTextView = onView(
            allOf(withId(android.R.id.text1), withText("tomato"), isDisplayed()));
appCompatTextView2.perform(click());

NoMatchingViewException:层次结构中没有找到匹配的视图:(id: android:id/text1 和 text: 是“番茄”并显示在屏幕上给用户)

我还看到一些人通过使用 sleeps 来实现这一点,但这对我来说并没有什么不同。有任何想法吗?谢谢

【问题讨论】:

    标签: android listview text adapter android-espresso


    【解决方案1】:

    我可以使用这里建议的答案:Espresso AutoCompleteTextView click

    onData(allOf(instanceOf(BaseIngredient.class), withContent(ingredient))).inRoot(RootMatchers.withDecorView(not(is(mActivityTestRule.getActivity().getWindow().getDecorView())))).perform(ViewActions.click());
    

    我必须创建一个自定义 Matcher,因为适配器中的每个元素都是一个 BaseIngredient 对象。

    public static Matcher<Object> withContent(final String title) {
        return new BoundedMatcher<Object, BaseIngredient>(BaseIngredient.class) {
            @Override
            public boolean matchesSafely(BaseIngredient myObj) {
                return myObj.mName.equals(title);
            }
    
            @Override
            public void describeTo(Description description) {
                description.appendText("with title '" + title + "'");
            }
        };
    }
    

    【讨论】: