Android Material Design验证Espresso测试失败:密码字段断言不匹配
先看你的测试代码:
@Test public void click_login_with_empty_fields_gives_errors() { onView(withId(R.id.login)).perform(click()); onView(withId(R.id.login_email2)).check(matches(hasErrorText("Email Field cannot be empty"))); onView(withId(R.id.login_password2)).check(matches(hasErrorText("Password field cannot be empty"))); }
错误提示显示密码输入框没有匹配到预期的错误文本,我整理了几个常见的排查方向:
1. 错误文本的大小写/拼写不一致
仔细核对你的字符串资源(比如strings.xml)里的密码错误提示文本,是不是和测试里写的"Password field cannot be empty"完全一致?比如有没有大小写差异(比如首字母大写的Password vs 小写的password),或者空格、标点符号的区别?很多时候这种不匹配都是因为字符串的细微差异导致的。
2. 错误提示是设置在TextInputLayout而非TextInputEditText上
如果你的布局用了TextInputLayout包裹TextInputEditText,那么错误提示是设置在TextInputLayout上的,而不是EditText本身。这时候你需要针对TextInputLayout来做检查,而不是它内部的EditText:
// 找到对应的TextInputLayout(假设它的id是login_password_layout) onView(withId(R.id.login_password_layout)) .check(matches(hasErrorText("Password field cannot be empty")));
如果不知道TextInputLayout的id,也可以用hasChild()或者withChild(withId(R.id.login_password2))来定位它:
onView(allOf(isAssignableFrom(TextInputLayout.class), withChild(withId(R.id.login_password2)))) .check(matches(hasErrorText("Password field cannot be empty")));
3. 测试执行速度太快,错误提示还没显示出来
有时候UI验证的动画或者异步处理会导致错误提示不是立刻显示的,这时候Espresso可能在提示出现前就执行了检查。可以添加一个等待条件,确保错误提示已经显示:
// 等待密码输入框的错误提示出现 onView(withId(R.id.login_password2)) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(hasErrorText("Password field cannot be empty")));
4. 验证逻辑的问题
检查你的登录按钮点击后的验证代码,是不是真的给密码字段设置了错误提示?比如有没有漏掉密码字段的空值判断,或者设置错误提示的代码写错了控件?比如是不是误把错误提示设置到了其他控件上?
可以先手动测试一遍,点击登录按钮,确认密码输入框(或者它的TextInputLayout)确实显示了预期的错误文本,再回到测试代码排查。
内容的提问来源于stack exchange,提问作者Chris

