如何在 R.id 的父元素中通过 class 名称访问元素

How to access a element by class name within a parent element with R.id

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

我在尝试编辑没有 R.id 但有 class 名称的元素中的文本时遇到问题 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)

问题是具有 class 名称 android.widget.EditText 的元素没有 R.id.。此 class 名称对于此视图不是唯一的,此具有 class 名称的元素 android.widget.EditText 具有具有唯一 R.id. 的父元素。

在应用程序的登录视图中,两个元素具有 class 名称 android.widget.EditText,因此我不能仅通过 class 名称来调用此元素。我想这样称呼它: 在具有 R.id.til_name 的元素中找到具有 class 名称的元素 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 我想找到一种简单的方法来调用它们以进行测试。

我认为您应该试试这个(找到没有 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())))

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

使用 isDescendantOfA 我们不必担心我们要查找的元素是否具有 parent/grandparent 和 R.id,它只需要在层次结构中较低。