Espresso:测试 TextInputLayout PasswordVisibilityToggle 按钮

Espresso: Test TextInputLayout PasswordVisibilityToggle button

美好的一天,我开始学习浓咖啡,并尝试检查 TextInputLayout 的 PasswordVisibilityToggleEnabled 按钮是否可见。我知道这个按钮是一个带有 id 的 CheckableImageButton (R.id.text_input_password_toggle) 但不确定如何在 Espresso 中获取它。

我试过这样做:

onView(withId(R.id.passwordTextInputLayout)).check(hasDescendant(withId(R.id.text_input_password_toggle))).check(matches(not(isDisplayed())));

但这不起作用。我猜想我可能必须根据 Whosebug 上的几个问题使用自定义匹配器,但我不确定我是否正确地这样做了。

public static Matcher<View> getPasswordToggleView(final Matcher<View> parentMatcher, int id) {
    return new TypeSafeMatcher<View>() {
        @Override
        protected boolean matchesSafely(View view) {
            if(!(view.getParent() instanceof ViewGroup)) {
                return parentMatcher.matches(view.getParent());
            }

            ViewGroup group = (ViewGroup) view.getParent();
            return  parentMatcher.matches(view.getParent()) && view.getId() == id;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("get View with matching id");
        }
    };
}

并尝试像这样使用它但仍然无法正常工作:

 onView(getPasswordToggleView(withId(R.id.passwordTextInputLayout), R.id.text_input_password_toggle)).check(matches(not(isDisplayed())));

有什么想法吗?

只要您(显然)已经可以使用切换按钮的 ID,您就可以执行此操作 onView(withId(R.id.text_input_password_toggle)).check(doesNotExist()) 来检查切换按钮是否未显示。如果 passwordToggleEnabled 为假,此验证将成功。

doesNotExistandroid.support.test.espresso.assertion

的一部分

在您的代码中:

onView(withId(R.id.passwordTextInputLayout))
    .check(hasDescendant(withId(R.id.text_input_password_toggle))) // assume you forgot matches(...)
    .check(matches(not(isDisplayed())));

最后一次检查 not(isDisplayed)) 是在 TextInputLayout 上执行的,而不是您预期的 CheckableImageButton。要修复此错误,只需将您的代码重新排列为:

onView(withId(R.id.passwordTextInputLayout))
    .check(matches(allOf(hasDescendant(withId(R.id.text_input_password_toggle)), not(isDisplayed()))))

以便它可以对按钮进行显示检查。

或者,如果您想为 TextInputLayout 创建自定义匹配器,您可以尝试:

public static Matcher<View> isPasswordVisibilityToggleEnabled() {
    return new BoundedMatcher<View, TextInputLayout>(TextInputLayout.class) {

        @Override public void describeTo(Description description) {
            description.appendText("is password visibility toggle enabled");
        }

        @Override protected boolean matchesSafely(TextInputLayout view) {
            return view.isPasswordVisibilityToggleEnabled();
        }
    };
}

那你可以把你的测试代码改成:

onView(withId(R.id.passwordTextInputLayout))
    .check(matches(not(isPasswordVisibilityToggleEnabled())))

我认为 view.isPasswordVisibilityToggleEnabled() 在这种情况下足以进行简单测试,但您可以随意调整匹配器。