【问题标题】:FooterView in ListView not found using Espresso使用 Espresso 找不到 ListView 中的 FooterView
【发布时间】:2025-12-25 03:40:11
【问题描述】:

我正在编写一个 espresso 测试,它检查在我以编程方式添加到 ListView 的 FooterView 中找不到 TextView。在 espresso 测试中找到 TextView 的唯一方法是等待 1 秒,然后再检查是否TextView 存在。

    // checks if the list view contains an issue that has the text "Do" somewhere
    onView(withId(R.id.listView)).check(matches(hasDescendant(withText(containsString("Do")))));
    // swipes down to access the load older issues button
    onView(allOf(withId(R.id.mainLayout))).perform(swipeUp());

    // View listView = shelfActivity.getActivity().findViewById(R.id.listView_footer_textview); // returns the view, even when espresso tells that it does not exist
    // Thread.sleep(1000); // need to wait in order to find the footerview of the list view

    // check if the load older issues button is here
    onView(allOf(withId(R.id.listView_footer_textview), isDisplayed())).check(matches(isDisplayed()));

FooterView 中的这个 TextView 实际上是存在的,如果我尝试使用正常的 findById() 方法获取它,我可以在同一个地方的测试中找到它,但是当我使用 espresso 检查它时找不到它。

所以我的问题是: 如果我想在 FooterView 中检查 TextView,我真的必须调用 Thread.sleep(1000) 才能通过测试吗?对我来说,espresso 的最大优势在于,我不必等待视图准备好,所以不存在自动执行此操作的 espresso 功能吗?

【问题讨论】:

    标签: android listview android-espresso


    【解决方案1】:

    可以通过onData方法找到ListView的FooterView。

    这里是official documents

    例如:

    public static final String FOOTER = "FOOTER";
    ...
    View footerView = layoutInflater.inflate(R.layout.list_item, listView, false);
    ((TextView) footerView.findViewById(R.id.item_content)).setText("count:");
    ((TextView) footerView.findViewById(R.id.item_size)).setText(String.valueOf(data.size()));
    listView.addFooterView(footerView, FOOTER, true);
    

    然后,你可以编写一个匹配这个对象的匹配器:

    import static org.hamcrest.Matchers.allOf;
    import static org.hamcrest.Matchers.instanceOf;
    import static org.hamcrest.Matchers.is;
    
    @SuppressWarnings("unchecked")
    public static Matcher<Object> isFooter() {
      return allOf(is(instanceOf(String.class)), is(LongListActivity.FOOTER));
    }
    

    在测试中加载视图很简单:

    import static com.google.android.apps.common.testing.ui.espresso.Espresso.onData;
    import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
    import static com.google.android.apps.common.testing.ui.espresso.sample.LongListMatchers.isFooter;
    
    public void testClickFooter() {
      onData(isFooter())
        .perform(click());
      ...
    }
    

    【讨论】:

    • 这不是我在页脚视图中找不到 textview 的问题,问题是我只有在让踏板休眠至少 1 秒后才找到它。同样的问题仍然存在,如果我将 is(LongListActivity.FOOTER) 标准添加到我的搜索中(实际上没有必要,因为搜索 id 就足够了)。如上所述,当我使用shelfActivity.getActivity().findViewById() 搜索相同的文本视图时,也不会出现此问题;在那种情况下,我会立即找到预期的文本视图,而无需休眠 1 秒。
    • 我无法理解这个问题,因为but fails to find a FooterView 有问题,never find the textview inside my footer view 在上面的评论中。 R.id.listView_footer 是 TextView 的 id 吗?
    • 对不起,描述不是很清楚,我现在编辑了。如果我在检查之前不调用 sleep(1000),它将无法在页脚视图中找到 textview。