在我的测试中,在一次操作之后,有两种可能的视图可以出现,并且它们都是正确的。如何检查是否显示其中一个视图。对于我可以检查的单个视图是Displayed()。但如果其他视图可见则会失败。如果显示这两个视图中的任何一个,我想通过测试。
onMyButton.perform(click());
onMyPageOne.check(matches(isDisplayed())); //view 1
or
onMyPageTwo.check(matches(isDisplayed())); //view 2
之后,执行点击MyButton,预计会出现任何一个视图(1或2),但不会同时出现。不确定哪一个会被显示。 如何检查是否显示其中任何一个?
答案 0 :(得分:45)
可以像以下一样抓住Espresso提出的例外情况:
如果要测试视图是否在层次结构中:
try {
onView(withText("Button")).perform(click());
// View is in hierarchy
} catch (NoMatchingViewException e) {
// View is not in hierarchy
}
如果层次结构中的视图不是,则会抛出此异常。
有时视图可以在层次结构中,但我们需要测试它是否显示,因此断言还有另一个例外,如:
try {
onView(withText("Button")).check(matches(isDisplayed()));
// View is displayed
} catch (AssertionFailedError e) {
// View not displayed
}
答案 1 :(得分:30)
这里有两种情况你可以尝试覆盖。第一种是,如果您正在检查视图"是否在屏幕上显示给用户" ,在这种情况下您将使用isDisplayed()
onView(matcher).check(matches(isDisplayed()));
或否定
onView(matcher).check(matches(not(isDisplayed())));
另一种情况是,如果您正在检查视图是否可见但不一定显示在屏幕上(即滚动视图中的项目)。为此,您可以使用withEffectiveVisibility(Visibility)
onView(matcher).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
答案 2 :(得分:20)
您可以使用Matchers.anyOf检查是否显示了两个视图中的任何一个:
onView(
anyOf(withId(R.id.view_1), withId(R.id.view_2))
).check(matches(isDisplayed()));
答案 3 :(得分:8)
我研究了Espresso,我找到了这个@ Espresso Samples。
搜索文本“断言未显示视图”。它说:“如果视图仍然是层次结构的一部分,则上述方法有效。”所以我认为你的代码应该可行,但你也需要使用ViewAssertions
。使用您的代码,也许这样做:
if (ViewAssertions.doesNotExist()) == null) {
return;
}
onMyPageOne.check(matches(isDisplayed()));
另一种技术是检查UI是否存在。搜索文本“断言视图不存在”。 使用您的代码,我最好的建议是:
onMyPageOne.check(doesNotExist());
注意:这会调用doesNotExist
方法。
他们的示例代码为:onView(withId(R.id.bottom_left)).check(doesNotExist());
答案 4 :(得分:6)
实用程序类,可以检查视图是gone
,invisible
还是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;
}
}
}
:
onView(withId(R.id.text_message)).check(isVisible());
用法可能如下所示:
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
}
}
}
:
alter table dim_known_hosts drop if exists PARTITION (dimensional_partition_folder<'2016_01_04_00_30');
答案 5 :(得分:3)
问题是所有assertoin()
和check()
方法都会返回Assertion
,如果失败则会停止测试流程。
答案 6 :(得分:3)
对于那些希望查看视图可见性状态的对象;这是我使用的一些实用程序功能。
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))
}
并且可以如下使用
onView(withId(R.id.progressBar)).isVisible()
onView(withId(R.id.progressBar)).isGone()
答案 7 :(得分:1)
检查View或其子类(如Button)的一种简单方法是使用方法 来自查看类的 getVisibility 。我必须提醒一下,在GUI世界中没有明确定义可见性属性。视图可能被认为是可见的,但可能与另一个视图重叠,例如,使其隐藏。
另一种方法,但更准确(我还没试过)是检查视图的矩形边界。不那么简单。
这是否足够清楚?因为你没有发布代码,所以不能给你具体的例子。
答案 8 :(得分:0)
final AtomicBoolean view1Displayed = new AtomicBoolean(true);
Espresso.onView(ViewMatchers.withId(viewId1)).inRoot(RootMatchers.withDecorView(Matchers.is(intentsTestRule.getActivity().getWindow().getDecorView()))).withFailureHandler(new FailureHandler() {
@Override
public void handle(Throwable error, Matcher<View> viewMatcher) {
view1Displayed.set(false);
}
}).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
if (view1Displayed.get()) {
try {
Espresso.onView(ViewMatchers.withId(viewId2)).inRoot(RootMatchers.withDecorView(Matchers.is(intentsTestRule.getActivity().getWindow().getDecorView()))).check(ViewAssertions.matches(Matchers.not(ViewMatchers.isDisplayed())));
} catch (NoMatchingViewException ignore) {
}
} else {
Espresso.onView(ViewMatchers.withId(viewId2)).inRoot(RootMatchers.withDecorView(Matchers.is(intentsTestRule.getActivity().getWindow().getDecorView()))).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
}
答案 9 :(得分:0)
当我遇到这种情况时,我通常会分为多个测试。一个测试设置要显示的视图1的条件,而另一项测试则设置要显示的视图2的条件。
但是,假设您无法真正控制条件。例如,如果它取决于随机数还是取决于第三方资源(例如服务器上的计算)怎么办?在那种情况下,我通常会解决模拟问题。这样,我可以控制条件,因此我确切地知道期望哪个视图。我使用依赖注入来设置每个测试所需的模拟。