【问题标题】:Espresso: Test TextInputLayout PasswordVisibilityToggle buttonEspresso:测试 TextInputLayout PasswordVisibilityToggle 按钮
【发布时间】:2019-03-12 18:50:18
【问题描述】:

美好的一天,我开始掌握 espresso 并尝试检查 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())));

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

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())));

有什么想法吗?

【问题讨论】:

    标签: android unit-testing android-espresso


    【解决方案1】:

    在您的代码中:

    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() 足以在这种情况下进行简单测试,但您可以随意调整匹配器。

    【讨论】:

    • 它不起作用。我得到一个:junit.framework.AssertionFailedError:'(有后代:ID:2131296788,而不是在屏幕上显示给用户)'与所选视图不匹配。预期:(有后代:id:com.MyPackageName:id/text_input_password_toggle,而不是在屏幕上显示给用户)似乎无法正确找到 ID
    • 当我像在你的示例中那样使用自定义 Matcher 时,它可以工作,但如果我尝试使用 Has 后代,我会像以前的 cmets 一样得到错误
    • 我可能是错的,但也许您在您的应用资源下创建了相同的 id 名称。如果是真的,那么只需将其删除。或者尝试将withId(R.id.text_input_password_toggle) 替换为ViewMatchers.isAssignableFrom(CheckableImageButton.class)。如果您希望禁用切换,请确保它是 not(isDisplayed())
    • 谢谢。出于某种原因,它仍然无法正常工作,但我已经同意您关于使用有效的自定义匹配器的其他建议。还是谢谢
    【解决方案2】:

    只要您(显然)已经很好地使用了切换按钮的 id,您就可以这样做onView(withId(R.id.text_input_password_toggle)).check(doesNotExist()) 来检查切换按钮是否不显示。如果passwordToggleEnabled 为假,此验证将成功。

    doesNotExistandroid.support.test.espresso.assertion 的一部分

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 2016-01-27
      • 2021-02-04
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多