如何使用R.id在父元素中按类名访问元素

时间:2019-06-28 11:57:49

标签: android android-espresso matcher android-espresso-recorder

我正在编写用于登录Android应用程序的自动测试。我正在使用Record Espresso Test记录测试,然后编辑代码,因为它通常充满了错误。 我正在使用浓缩咖啡 androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2',uiAutomatorViewer仔细检查R.id's~class的名称。

在尝试编辑元素名称为R.id而不是android.widget.EditText的元素中的文本时遇到了问题:

android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (with id: com.mydosesmart:id/til_name and an instance of android.widget.FrameLayout and an instance of android.widget.EditText)

问题是类名称为android.widget.EditText的元素没有R.id.。该类名称在该视图中不是唯一的,该类名称为android.widget.EditText的元素具有一个父元素,该元素具有唯一的R.id.

在应用程序的登录视图中,两个元素的类名称为android.widget.EditText,因此我不能仅通过类名称来调用此元素。我想这样称呼它: 在具有R.id.til_name的元素中找到具有类名android.widget.EditText的元素。下面是我现在使用的代码,但失败了。

ViewInteraction textInputEditText2 = onView(
                allOf(withId(R.id.til_name), instanceOf(Class.forName("android.widget.FrameLayout")), instanceOf(Class.forName("android.widget.EditText"))));
        textInputEditText2.perform(replaceText("testespresso"), closeSoftKeyboard());

那也失败了:

ViewInteraction textInputEditText2 = onView(
                allOf(withId(R.id.til_name), instanceOf(Class.forName("android.widget.EditText"))));
        textInputEditText2.perform(replaceText("testespresso"), closeSoftKeyboard());

由于我正在测试的应用程序中有很多元素都没有指定R.id,因此我想找到一种简单的方法来调用它们以进行测试。

2 个答案:

答案 0 :(得分:1)

我认为您应该尝试此操作(以找到没有ID但父代具有唯一已知ID的EditText):

allOf(withParent(withId(R.id...)), withClassName(containsString(EditText.class.getName())))

基于新信息进行更新:与间接父级匹配(R.id ....是放置间接父级ID的位置):

allOf(isDescendantOfA(withId(R.id...)), withClassName(containsString(EditText.class.getName())))

答案 1 :(得分:1)

尝试了所有可能的组合使用了数十种不同的匹配器后,我找到了问题的答案。到目前为止,它似乎是通用的: onView(allOf(withClassName(containsString(EditText.class.getSimpleName())), isDescendantOfA(withId(R.id.til_name)))) .perform(replaceText("testespresso "), closeSoftKeyboard());

使用isDescendantOfA,我们不必担心所寻找的元素是否具有R.id的父/祖父母,只需将其放在层次结构中较低的位置即可。