问题描述
我有一个包含 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
...否则您最终可能需要编写自定义视图匹配器。