如何用Espresso测试Android中AutoCompleteTextView的弹窗状态?
Espresso 验证AutoCompleteTextView 建议弹窗状态的正确方式
问题根源
你之前的代码问题在于:
- 使用
onData(anything())模糊匹配所有数据时,Espresso会持续等待符合条件的数据出现,当弹窗关闭时,这种等待会导致超时或无限循环。 - 直接检查数据是否存在/显示,没有针对弹窗的根视图做精准判断,容易出现误判。
1. 验证弹窗已打开(输入"d"显示"def"场景)
针对具体数据做匹配,避免模糊匹配带来的问题:
// 先向AutoCompleteTextView输入"d" onView(withId(R.id.your_autocomplete_id)) .perform(typeText("d"), closeSoftKeyboard()); // 验证弹窗中正确显示"def" onData(allOf(is(instanceOf(String.class)), is("def"))) .inRoot(RootMatchers.isPlatformPopup()) .check(matches(isDisplayed()));
2. 验证弹窗已关闭(输入"g"后弹窗消失场景)
直接检查平台弹窗根视图不存在,这比检查数据不存在更可靠:
// 继续输入"g" onView(withId(R.id.your_autocomplete_id)) .perform(typeText("g"), closeSoftKeyboard()); // 等待UI空闲,确保弹窗完成关闭逻辑 Espresso.waitForIdleSync(); // 断言当前没有平台弹窗根视图存在 onView(isRoot()) .check(matches(not(isPlatformPopupRoot())));
辅助Matcher:判断是否为平台弹窗根视图
需要自定义一个Matcher来精准识别平台弹窗的根视图:
private static Matcher<View> isPlatformPopupRoot() { return new TypeSafeMatcher<View>() { @Override protected boolean matchesSafely(View view) { Root root = (Root) view.getLayoutParams(); WindowManager.LayoutParams params = root.getWindowLayoutParams().get(); return params.type == WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL && params.token == view.getApplicationWindowToken(); } @Override public void describeTo(Description description) { description.appendText("is platform popup root"); } }; }
补充说明
- 尽量避免
onData(anything())这类模糊匹配,针对具体数据或视图属性匹配能减少Espresso的等待时间和误判概率。 - 执行输入操作后记得调用
closeSoftKeyboard(),避免软键盘遮挡或干扰弹窗状态判断。
内容的提问来源于stack exchange,提问作者Laurent D.
相关产品推荐
相关产品推荐

