Android Espresso 在自定义视图类中找不到 Edittext

问题描述

Possible Duplicate 1

Possible Duplicate 2

我有一个包含 textview 和 edittext 的自定义视图。我想在我的自定义视图中访问 Edittext 以进行 UI 测试。但我不想使用自定义 ViewAction 来 setEdittext,因为在这种情况下我将无法支持 typeText 之类的方法。这是我的测试方法

@RunWith(AndroidJUnit4::class)
class LoginFragmentTest : Basetest() {
  @Test
  @Throws(InterruptedException::class)
  fun testLoginForm() {
    val navController = TestNavHostController(ApplicationProvider.getApplicationContext())
    val loginScenario = launchFragmentInContainer<LoginFragment>()
    loginScenario.onFragment { fragment ->
        navController.setGraph(R.navigation.nav_login)
        Navigation.setViewNavController(fragment.requireView(),navController)
    }
    onView(allOf(withId(R.id.etForm),isDescendantOfA(withId(R.id.email)))).perform(typeText("user@email.com"))
    onView(allOf(withId(R.id.etForm),isDescendantOfA(withId(R.id.password)))).perform(typeText("123456"))
    onView(withId(R.id.login)).perform(click())
  }
}

我收到以下错误

androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (with id is <com.example.cicddemo:id/etForm> and is descendant of a: with id is <2131296433>)

注意:我已经通过自定义 ViewAction 实现了它,它工作正常。但我无法获得 typeText 功能

ViewonView(withId(R.id.email)).perform(setTextEditText(newText = "user@email.com"))
onView(withId(R.id.password)).perform(setTextEditText(newText = "123456"))

自定义视图操作:

fun setTextEditText(
newText: String ?
): ViewAction {
return object: ViewAction {

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

    override fun getDescription(): String {
        return "Update the text from the custom EditText"
    }

    override fun perform(uiController: UiController ?,view : View) {
        (view as FormView).setText(newText)
    }
}
}

是否可以访问自定义视图类中的实际编辑文本并通过它进行测试?

解决方法

我通过在不使用任何自定义 ViewAction 的情况下按标签检索视图解决了我的问题。问题是在我的自定义视图中我使用了

etForm.id = View.generateViewId()

由于 id 在运行时发生变化,所以我正在设置标签和访问权限

withTagValue

这是更新的代码

@Test
@Throws(InterruptedException::class)
fun testInvalidEmailPassword() {
    val emailViewInteraction = onView(allOf(withTagValue(`is`("email" as Any?)),isDescendantOfA(withId(R.id.email))))
    val passwordViewInteraction = onView(allOf(withTagValue(`is`("password" as Any?)),isDescendantOfA(withId(R.id.password))))
    emailViewInteraction.perform(typeText("user@email.com"))
    passwordViewInteraction.perform(typeText("123456"))
    onView(withId(R.id.login)).perform(click())
}
,

如果这是 AWS FormView,只需匹配它扩展的 LinearLayout

...否则您最终可能需要编写自定义视图匹配器。