Android Espresso:如何将文本输入到嵌入 TextInputLayout 的 editText 中

问题描述 投票:0回答:4

寻找一种方法将 Text 或 typeText 替换为嵌入 TextInputLayout 中的编辑文本。

我尝试过一些这样的事情:

perform(ViewActions.typeTextIntoFocusedView("String")); 

但我总是以这个结束:

java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
(((is displayed on the screen to the user) and has focus on the screen to the user) and (supports input methods or is assignable from class: class android.widget.SearchView))
android android-edittext android-espresso textinputlayout
4个回答
1
投票

您必须创建一个新的

ViewAction
,因为 Espresso 无法访问嵌入在
EditText
中的
TextInputLayout
。你可以使用这样的东西

class TextInputLayoutActions {
    class ReplaceTextAction(private val text: String): ViewAction {
        override fun getDescription(): String {
            return String.format(Locale.ROOT, "replace text(%s)", text)
        }

        override fun getConstraints(): Matcher<View> {
            return allOf(isDisplayed(), ViewMatchers.isAssignableFrom(TextInputLayout::class.java))
        }

        override fun perform(uiController: UiController?, view: View?) {
            (view as? TextInputLayout?)?.let {
                it.editText?.setText(text)
            }
        }

    }

    companion object {
        @JvmStatic
        fun replaceText(text: String): ViewAction {
            return actionWithAssertions(ReplaceTextAction(text))
        }
    }
}

然后像这样使用它

<ViewInteraction>.perform(TextInputLayoutActions.replaceText(<text>)

0
投票

我尝试了这种方式如果您有权访问该活动,您也可以使用 findviewById

 @Test
fun testSave() {
    val book = Book(
        title = "Machine Learning",
        author = "Mohammed Fahim khan",
        year = "2021", imageUrl = ""
    )
    val testViewModel = BookViewModel(FakeBookRepositoryIT())
    launchFragmentInHiltContainer<BookDetailsFragment>(factory = fragmentFactory) {
        viewModel = testViewModel
        binding.etTitle.editText?.setText(book?.title.toString())
        binding.etName.editText?.setText(book?.author.toString())
        binding.etYear.editText?.setText(book?.year.toString())

    }


    /*onView(withId(R.id.et_title)).perform(replaceText(book.title))
    onView(withId(R.id.et_name)).perform(replaceText(book.author))
    onView(withId(R.id.et_year)).perform(replaceText(book.year))*/
    onView(withId(R.id.btn_save)).perform(click())
    val list = testViewModel.bookList.getOrAwaitValue()
    assertThat(list).contains(book)
}

0
投票

很简单:

onView(withId(R.id.YOUR_INPUT)).perform(typeText("bla bla"))

0
投票

我知道我对这个问题晚了几年,我无法告诉你哪种方法是最好的,但到目前为止提出的答案对我来说似乎过于复杂。

在我自己的测试中,我成功地将值放入嵌入

TextInputEditText
中的
TextInputLayout
中,方法是识别父级
TextInputLayout
,然后找到具有以“EditText”结尾的类的后代视图,该类应覆盖
EditText
TextInputEditText

onView(allOf(
    isDescendantOfA(withId(R.id.tilTicketNum)),
    withClassName(endsWith("EditText")))
).perform(scrollTo(), replaceText("123456"));

如果您向

TextInputLayout
添加多个子视图,您可能会遇到这种方法的麻烦,但我很确定这违反了材料设计标准,所以我认为在大多数情况下这不应该成为问题。

仅供参考,我目前正在使用:

  • androidx.test.espresso:espresso-core:3.6.0-alpha03
  • org.hamcrest:hamcrest-library:1.3
© www.soinside.com 2019 - 2024. All rights reserved.