Espresso - 如何检查是否显示其中一个视图

use*_*316 50 java listview android-testing android-espresso

在我的测试中,在一次操作之后,有两种可能的视图可以出现并且它们都是正确的.如何检查是否显示其中一个视图.对于我可以检查的单个视图是Displayed().但如果其他视图可见则会失败.如果显示这两个视图中的任何一个,我想通过测试.

onMyButton.perform(click());

onMyPageOne.check(matches(isDisplayed())); //view 1
or
onMyPageTwo.check(matches(isDisplayed())); //view 2
Run Code Online (Sandbox Code Playgroud)

之后,执行单击MyButton,预计会出现任何一个视图(1或2),但不会同时出现.不确定哪一个会被显示.如何检查是否显示其中任何一个?

Laf*_*tte 53

可以捕获Espresso提出的异常,如下所示:

如果要测试视图是否在层次结构中:

try {
    onView(withText("Button")).perform(click());
    // View is in hierarchy

} catch (NoMatchingViewException e) {
    // View is not in hierarchy
}
Run Code Online (Sandbox Code Playgroud)

如果视图不在层次结构中,则抛出此异常.

有时视图可以在层次结构中,但我们需要测试它是否显示,因此断言还有另一个例外,如下所示:

try {
    onView(withText("Button")).check(matches(isDisplayed()));
    // View is displayed
} catch (AssertionFailedError e) {
    // View not displayed
}
Run Code Online (Sandbox Code Playgroud)

  • 你必须等待超时,而不是搞乱超时,只是检查"这是这件事,是或否"会更好.我在这里的唯一原因是我需要减少云设备测试的设备分钟数.仅仅等待30秒才能达到异常是不够的,并且在上下文中管理超时感觉不对 (3认同)

RyP*_*ope 34

这里有两种情况你可以尝试覆盖.第一种是,如果您正在检查视图"是否在屏幕上显示给用户",在这种情况下您将使用isDisplayed()

onView(matcher).check(matches(isDisplayed()));
Run Code Online (Sandbox Code Playgroud)

或否定

onView(matcher).check(matches(not(isDisplayed())));
Run Code Online (Sandbox Code Playgroud)

另一种情况是,如果您正在检查视图是否可见但不一定显示在屏幕上(即滚动视图中的项目).为此您可以使用withEffectiveVisibility(Visibility)

onView(matcher).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
Run Code Online (Sandbox Code Playgroud)


Lui*_*sto 22

您可以使用Matchers.anyOf检查是否显示了两个视图中的任何一个:

onView(
   anyOf(withId(R.id.view_1), withId(R.id.view_2)) 
).check(matches(isDisplayed()));
Run Code Online (Sandbox Code Playgroud)

  • 此代码无法确保准确显示 2 个视图中的 1 个。你确定是这样吗? (2认同)

The*_*oid 8

我稍微研究了Espresso,我发现了这个@ Espresso样品.

  1. 搜索文本"断言未显示视图".它说:"如果视图仍然是层次结构的一部分,则上述方法有效." 所以我认为你的代码应该可行,但你也需要使用它ViewAssertions.使用您的代码,也许这样做:

    if (ViewAssertions.doesNotExist()) == null) {
       return;
    }
    onMyPageOne.check(matches(isDisplayed()));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 另一种技术是检查UI是否存在.搜索文本"断言视图不存在".使用您的代码,我最好的建议是:

    onMyPageOne.check(doesNotExist());

注意:此调用doesNotExist方法.

他们的示例代码是: onView(withId(R.id.bottom_left)).check(doesNotExist());

  • 这是一个使用.我没有(isDisplayed()):( (3认同)

dgn*_*can 7

对于那些希望查看视图可见性状态的对象;这是我使用的一些实用程序功能。

fun ViewInteraction.isGone() = getViewAssertion(ViewMatchers.Visibility.GONE)

fun ViewInteraction.isVisible() = getViewAssertion(ViewMatchers.Visibility.VISIBLE)

fun ViewInteraction.isInvisible() = getViewAssertion(ViewMatchers.Visibility.INVISIBLE)

private fun getViewAssertion(visibility: ViewMatchers.Visibility): ViewAssertion? {
    return ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(visibility))
}
Run Code Online (Sandbox Code Playgroud)

并且可以如下使用

onView(withId(R.id.progressBar)).isVisible()
onView(withId(R.id.progressBar)).isGone()
Run Code Online (Sandbox Code Playgroud)


ele*_*ven 6

实用程序类,允许检查视图是否visible,goneinvisible:

public class ExtraAssertions {
    public static ViewAssertion isVisible() {
        return new ViewAssertion() {
            public void check(View view, NoMatchingViewException noView) {
                assertThat(view, new VisibilityMatcher(View.VISIBLE));
            }
        };
    }

    public static ViewAssertion isGone() {
        return new ViewAssertion() {
            public void check(View view, NoMatchingViewException noView) {
                assertThat(view, new VisibilityMatcher(View.GONE));
            }
        };
    }

    public static ViewAssertion isInvisible() {
        return new ViewAssertion() {
            public void check(View view, NoMatchingViewException noView) {
                assertThat(view, new VisibilityMatcher(View.INVISIBLE));
            }
        };
    }

    private static class VisibilityMatcher extends BaseMatcher<View> {

        private int visibility;

        public VisibilityMatcher(int visibility) {
            this.visibility = visibility;
        }

        @Override public void describeTo(Description description) {
            String visibilityName;
            if (visibility == View.GONE) visibilityName = "GONE";
            else if (visibility == View.VISIBLE) visibilityName = "VISIBLE";
            else visibilityName = "INVISIBLE";
            description.appendText("View visibility must has equals " + visibilityName);
        }

        @Override public boolean matches(Object o) {

            if (o == null) {
                if (visibility == View.GONE || visibility == View.INVISIBLE) return true;
                else if (visibility == View.VISIBLE) return false;
            }

            if (!(o instanceof View))
                throw new IllegalArgumentException("Object must be instance of View. Object is instance of " + o);
            return ((View) o).getVisibility() == visibility;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法可能如下所示:

onView(withId(R.id.text_message)).check(isVisible());
Run Code Online (Sandbox Code Playgroud)

另一种观点断言这将有助于检查视图的额外知名度性质及其家长:它检查visibility,isAttachedToWindow,alpha:

class IsVisible : ViewAssertion {
    override fun check(view: View, noViewFoundException: NoMatchingViewException?) {
        ViewMatchers.assertThat(
                "View is not visible. " +
                        "visibility: ${view.visibility}, " +
                        "isAttachedToWindow: ${view.isAttachedToWindow}, " +
                        "alpha: ${view.alpha}",
                true, `is`(isViewTreeVisible(view)))
    }

    private fun isViewTreeVisible(view: View?): Boolean {
        return if (view != null) {
            val viewVisible = view.isAttachedToWindow && view.visibility == View.VISIBLE && view.alpha == 1.0f

            if (view.parent !is View) viewVisible
            else viewVisible && isViewTreeVisible(view.parent as View)
        } else {
            true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


The*_*oid 1

检查 View 或其子类(如 Button)的一种简单方法是使用 View类中的getVisibility方法。我必须提醒大家,可见性属性在 GUI 世界中没有明确定义。视图可以被认为是可见的,但可以与另一个视图重叠,例如,使其隐藏。

另一种更准确的方法(我没有尝试过)是检查视图的矩形边界。没那么简单。

这够清楚了吗?由于您没有发布代码,因此无法给您具体示例。