You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Espresso测试中按位置选中Tab Layout的指定标签页

Solution: Select TabLayout Tabs by Position in Espresso

Got it, dealing with a TabLayout that has 114 tabs is definitely a case where text-based selection isn't scalable—random testing would be a nightmare otherwise! Here's a reliable way to target tabs by their position instead:

Step 1: Create a Custom childAtPosition Matcher

Espresso doesn't have a built-in matcher to target a child view by its position in a parent, so we'll make our own. This matcher checks if a view is the Nth child of a parent that matches your specified criteria (like your TabLayout's ID).

Java Implementation:

import android.view.View;
import android.view.ViewGroup;
import androidx.test.espresso.matcher.ViewMatchers;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

public static Matcher<View> childAtPosition(
        final Matcher<View> parentMatcher, final int position) {

    return new TypeSafeMatcher<View>() {
        @Override
        public void describeTo(Description description) {
            description.appendText("Child at position " + position + " in parent ");
            parentMatcher.describeTo(description);
        }

        @Override
        public boolean matchesSafely(View view) {
            ViewParent parent = view.getParent();
            return parent instanceof ViewGroup && parentMatcher.matches(parent)
                    && ((ViewGroup) parent).getChildAt(position).equals(view);
        }
    };
}

Kotlin Implementation:

import android.view.View
import android.view.ViewGroup
import androidx.test.espresso.matcher.ViewMatchers
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.TypeSafeMatcher

fun childAtPosition(parentMatcher: Matcher<View>, position: Int): Matcher<View> {
    return object : TypeSafeMatcher<View>() {
        override fun describeTo(description: Description) {
            description.appendText("Child at position $position in parent ")
            parentMatcher.describeTo(description)
        }

        override fun matchesSafely(view: View): Boolean {
            val parent = view.parent
            return parent is ViewGroup && parentMatcher.matches(parent)
                    && parent.getChildAt(position) == view
        }
    }
}

Step 2: Use the Matcher to Click a Tab by Position

Now you can target any tab using its index (note: positions start at 0—so the first tab is position 0, the 114th tab is position 113).

Example Code (Java):

// Replace R.id.your_tablayout_id with your actual TabLayout ID
// This clicks the 10th tab (index 9)
Espresso.onView(childAtPosition(ViewMatchers.withId(R.id.your_tablayout_id), 9))
        .perform(ViewActions.scrollTo(), ViewActions.click());

Example Code (Kotlin):

// Replace R.id.your_tablayout_id with your actual TabLayout ID
// This clicks the 50th tab (index 49)
onView(childAtPosition(withId(R.id.your_tablayout_id), 49))
    .perform(scrollTo(), click())

Key Notes:

  • Scrolling: For tabs that aren't visible on screen (which most of your 114 tabs will be), add the scrollTo() action before click()—Espresso will handle scrolling the TabLayout to bring the target tab into view.
  • Position Index: Double-check the index (0-based!) to avoid clicking the wrong tab.
  • TabLayout-ViewPager Binding: As long as your TabLayout is properly linked to the ViewPager, clicking the tab will automatically trigger the ViewPager to switch to the corresponding page—no extra code needed for the ViewPager itself.

This approach works consistently even with large numbers of tabs, so you can easily randomize positions for your testing (e.g., generate a random integer between 0 and 113 to pick a tab).

内容的提问来源于stack exchange,提问作者Vinayak B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:11:42