Android Espresso 测试 withHint 不起作用

Posted

技术标签:

【中文标题】Android Espresso 测试 withHint 不起作用【英文标题】:Android Espresso testing withHint doesn't work 【发布时间】:2017-12-19 18:29:30 【问题描述】:

我目前正在尝试将 Espresso UI 测试添加到我的 android 应用程序中,我希望能够通过它的提示字段定位 TextInputEditText,然后单击它并输入一些文本。 (我知道以 id 为目标是更好的做法,但在这种情况下我需要以提示为目标)

这是我尝试这样做的方法:

Espresso.onView(Matchers.allOf(Matchers.instanceOf(TextInputEditText::class.java),
            ViewMatchers.withHint("My Hint"))).
            perform(ViewActions.click(), ViewActions.typeText("type this"))

但是在尝试执行此操作时,我收到以下错误:

android.support.test.espresso.NoMatchingViewException:在层次结构中找不到匹配的视图:(android.support.design.widget.TextInputEditText 的一个实例并带有提示:是“旧密码”)

即使输出显示层次结构实际上确实持有此视图,如下所示:

TextInputEditTextid=2131820762, res-name=input_data, visibility=VISIBLE, width=1328, height=168, has-focus=true, has-focusable=true, has-window-焦点=真,可点击=真,已启用=真,已聚焦=真,可聚焦=真,已布局请求=假,已选=假,根-已布局请求= false, has-input-connection=true, editor-info=[inputType=0x80091 imeOptions=0x8000005 privateImeOptions=null actionLabel=null actionId=0 initialSelStart=0 initialSelEnd=0 initialCapsMode=0x0 hintText=我的提示 label=null packageName=null fieldId=0 fieldName=null extras=null hintLocales=null contentMimeTypes=null ], x=0.0, y=0.0, text=, input-type=524433, ime-target=true, has-links=错误

Espresso 中的 ViewMatchers.withHint 方法是否损坏,或者是否有特定的使用方法?为什么它找不到视图但在输出中实际显示它在层次结构中?

【问题讨论】:

您不能删除 instanceOf() 匹配器并仅使用 withHint() 的任何原因?在编写 Espresso 测试时,我尝试将实现细节排除在外,以便它们在底层实现发生变化时更加灵活。如果您使用支持库,其中完成相同行为的底层类通常因操作系统变体而不同,这一点也很重要。 如果我只使用 withHint() 恐怕问题还是一样。 确保在您手动打开应用程序时显示提示。 Espresso 不是在寻找您在输出中看到的hintText 属性(hintText 是编辑器信息的一部分),但您还应该有属性“hint=My Hint”(对我来说,它位于“text=”和“input-type”之间”)。此外,尝试在调试中查看该 textView.getHint() 的值是什么,因为这是匹配器寻找的值提示。 【参考方案1】:

Logcat 中的打印可能会产生误导。如果您的TextInputEditText 是启用了提示的TextInputLayout 的子视图,则TextInputLayout 将通过TextInputLayout.setHint 在其自身内部设置相同的提示,然后将TextInputEditText 上的提示设置为null。

您需要创建一个自定义匹配器来匹配 TextInputEditText 的提示作为解决方法:

fun withHint(title: String): Matcher<View> = withHint(equalTo(title))

fun withHint(matcher: Matcher<String>): Matcher<View> = object : BoundedMatcher<View, TextInputEditText>(TextInputEditText::class.java) 
    override fun describeTo(description: Description) 
        description.appendText("with hint: ")
        matcher.describeTo(description)
    

    override fun matchesSafely(item: TextInputEditText): Boolean 
        val parent = item.parent.parent
        return if (parent is TextInputLayout) matcher.matches(parent.hint) else matcher.matches(item.hint)
    

只需将您的 ViewMatchers.withHint("My Hint") 替换为 TextInputEditTextCustomMatchers.withHint("My Hint")

【讨论】:

【参考方案2】:

已经为此打开了一个错误。见:https://issuetracker.google.com/issues/37139118

【讨论】:

以上是关于Android Espresso 测试 withHint 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Android Espresso单元测试

Android 自动化测试 Espresso篇:异步代码测试

Android Studio 2.2 Espresso Test Recorder-----解放双手,通过录制测试过程实现测试

运行 Espresso 测试时在 Android Studio 中找不到属性 android:forceQueryable

Android Marshmallow:使用 Espresso 测试权限?

Android Espresso 测试:找不到类:...空测试套件