2015-03-25 80 views
32

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

onMyButton.perform(click()); 

onMyPageOne.check(matches(isDisplayed())); //view 1 
or 
onMyPageTwo.check(matches(isDisplayed())); //view 2 

后,上myButton的执行点击,该视图中的任何一个(1或2)预计将出现但不能同时。不能确定显示哪一个。 如何检查是否显示其中一个?

+0

根据链路https://code.google.com/p/android-test-kit/wiki/EspressoSamples#Asserting_that_a_view_is_not_displayed,“上述方法效果如果视图仍然是层级的一部分“。在“声明不显示视图”中搜索文本。 – 2015-03-25 17:22:41

回答

1

一个简单的方法来检查查看或它的子类如Button是使用方法 getVisibility查看类。我必须警告,可见性属性在GUI界面中没有明确定义。一个视图可能被视为可见,但可能与另一个视图重叠,例如,使其隐藏。

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

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

+0

我编辑了这个问题,使其更清晰。 – user846316 2015-03-25 10:32:38

+0

感谢您的代码更新。我不知道Espresso是一个测试库。无论如何,我张贴另一个答案。至少我知道Java和Android。 – 2015-03-25 17:14:58

5

我研究了一下Espresso,我发现这个@Espresso Samples

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

    if (ViewAssertions.doesNotExist()) == null) { 
        return; 
    } 
    onMyPageOne.check(matches(isDisplayed())); 
    
  2. 另一种技术是检查UI的存在。搜索文字“断言视图不存在”。 使用你的代码,我最好的建议是:

    onMyPageOne.check(doesNotExist());

注意:这个调用方法是doesNotExist

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

+3

这是一个使用。 (isDisplayed()):( – 2017-04-02 22:39:02

2

的问题是,所有assertoin()check()方法返回Assertion如果失败时停止测试流程。

+0

正是这个问题!我不知道是否有任何方法可以做到这一点。任何浓缩咖啡专家? – user846316 2015-03-30 17:49:45

+0

这应该是一个评论,我猜 – 2017-01-08 20:40:58

33

有可能赶上的咖啡这样抛出的异常:

如果你想测试一个观点是在层次结构:

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秒来发生异常,并根据上下文管理超时感觉错误 – 2017-04-20 14:41:10

+0

期望异常通常是一种代码异味,但我想解析一些例外情况就像解析未知输入 - 但即使这是有争议的。 – RyPope 2017-12-20 07:28:56

+0

我喜欢这个答案,本质上问题是,如果有任何API可以返回布尔值(true或false)而不是ViewAssertion来告诉用户元素是否可见,这是有用的,所以自动化fu职能测试可以进行相应的编码。 – 2018-01-01 21:42:05

5

的实用工具类,允许检查的观点是visiblegoneinvisible

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()); 
12

您可以使用Matchers.anyOf检查任何两个视图显示:

onView(
    anyOf(withId(R.id.view_1), withId(R.id.view_2)) 
).check(matches(isDisplayed())); 
+0

要检查是否显示视图1或视图2,可以在viewMatcher上使用anyOf。 – 2016-06-21 17:26:26

+1

此代码无法确保显示2个视图中的1个。你确定它确实吗? – dira 2017-01-25 09:34:13

11

这里有两个案例,你可能会试图掩盖。第一个是,如果你如果视图“显示在屏幕上向用户”在这种情况下,你可以使用isDisplayed()

onView(matcher).check(matches(isDisplayed())); 

或否定

onView(matcher).check(matches(not(isDisplayed()))); 

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

onView(matcher).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))); 
+0

谢谢@RyPope,可见性测试工作。 – user1510006 2017-12-15 03:26:35

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())); 
    }