Espresso 选择包含布局的子项

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

我一直在使用 Espresso 通过 Android 应用程序进行自动化 UI 测试。 (我一直在下班回家时试图找到问题的解决方案,所以我没有确切的示例和错误,但我可以明天早上更新)。我遇到了一个布局中的单元测试按钮的问题,该布局多次包含在单个用户界面中。下面是一个简单的例子:

<include 
   android:id="@+id/include_one"
   android:layout="@layout/boxes" />

<include 
   android:id="@+id/include_two"
   android:layout="@layout/boxes" />

<include 
    android:id="@+id/include_three"
    android:layout="@layout/boxes" />

这是 @layout/boxes 中内容的示例:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button1" />
    <Button
        android:id="@+id/button2" />
</RelativeLayout>

我似乎无法访问我想要的“include_one”包含中的按钮一,而不访问所有三个按钮。

我尝试使用以下方式访问按钮:

onView(allOf(withId(R.id.include_one), isDescendantOfA(withId(R.id.button1)))).perform(click());

onView(allOf(withId(R.id.button1), hasParent(withId(R.id.include_one)))).perform(click());

我从这个答案中找到了这两个:onChildView 和 hasSiblings with Espresso不幸的是我没有取得任何成功!

我知道这不太好,但由于我不在工作计算机上,我无法告诉你我遇到的确切错误,但我遇到过:

com.google.android.apps.common.testing.ui.espresso.AmbiguousViewMatcherException

还有一个错误告诉我没有找到匹配项。

我使用的代码是有道理的,尽管我是使用 Espresso 的新手,任何人都可以提供一些建议,或者指出我可能误解的内容吗?

android android-espresso
3个回答
34
投票

在同一布局中多次尝试使用相同的自定义 xml 时,这是一个常见的陷阱。


如果您现在尝试致电

<include/>

由于 
boxes.xml

被包含多次,因此您将始终得到第一个子布局中存在的按钮,而不会出现另一个子布局。 你已经非常接近了,但是你需要使用

withParent()

视图匹配器。 Button button1 = (Button) findViewById(R.id.button1);



3
投票

onView(allOf(withId(R.id.button1), withParent(withId(R.id.include_one)))) .check(matches(isDisplayed())) .perform(click());

然后创建一个辅助方法

private static final class WithParentMatcher extends TypeSafeMatcher<View> { private final Matcher<View> parentMatcher; private int hierarchyLevel; private WithParentMatcher(Matcher<View> parentMatcher, int hierarchyLevel) { this.parentMatcher = parentMatcher; this.hierarchyLevel = hierarchyLevel; } @Override public void describeTo(Description description) { description.appendText("has parent matching: "); parentMatcher.describeTo(description); } @Override public boolean matchesSafely(View view) { ViewParent viewParent = view.getParent(); for (int index = 1; index < hierarchyLevel; index++) { viewParent = viewParent.getParent(); } return parentMatcher.matches(viewParent); } }

这是用法

public static Matcher<View> withParent(final Matcher<View> parentMatcher, int hierarchyLevel) { return new WithParentMatcher(parentMatcher, hierarchyLevel); }



0
投票

onView(allOf(withId(R.id.button1), withParent(withId(R.id.include_one), 2))).perform(click());

	
© www.soinside.com 2019 - 2024. All rights reserved.