【问题标题】:Testing ViewPager with multiple fragments using android espresso使用 android espresso 测试具有多个片段的 ViewPager
【发布时间】:2015-08-06 13:11:57
【问题描述】:

我正在尝试测试使用 ViewPager 的应用程序。每个页面都包含片段,但这些片段并不总是可见的。我想检查当前可见页面中片段的可见性。

onView(withId(R.id.container_weather))
    .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));

但问题是 espresso 看起来是所有页面,而不仅仅是当前页面,我收到以下错误:

android.support.test.espresso.AmbiguousViewMatcherException: 'with id: eu.airpatrol.android:id/container_weather' 匹配层次结构中的多个视图...

【问题讨论】:

    标签: android automated-tests android-espresso


    【解决方案1】:

    我遇到了同样的问题,但是使用条件isCompletelyDisplayed() 解决了这个问题,因为它只考虑了屏幕上的视图。

    所以,这样的事情应该可以工作:

    onView(allOf(withId(R.id.container_weather), isCompletelyDisplayed()))
    .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
    

    注意:isDisplayed() 在某些情况下也可以工作,但它也会考虑屏幕外的视图,如果 ViewPager 加载了具有相同视图 ID 的任何其他页面 pr 片段,则它将不起作用。

    【讨论】:

      【解决方案2】:

      由于多个元素具有相同的 id,您的测试失败。您可以使用allOf(...) 组合条件。然后使用isDisplayed() 检查匹配的视图在屏幕上是否可见。下面的例子可以工作:

      onView(allOf(
          withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE),
          withId(R.id.container_weather)))
          .check(matches(isDisplayed()));
      

      【讨论】:

      • 感谢您的回复,我尝试了您的解决方案,但仍然存在同样的问题。我有两个页面,都包含这个片段,出于某种原因,在视图层次结构中都有可见性=可见。
      • R.id.container_weather 中是否有一些独特的文本或子元素?如果是,您也可以在 allOf() 中添加此检查。
      • 两者之间的唯一区别是y坐标,因为两者在不同的页面上。 :(
      • 您找到解决方案了吗?我遇到了同样的问题。在我的情况下,两个片段完全相同,只有它们显示的数据是唯一的区别
      • 使用allOf() 为我解决了这个问题(谢谢),但请注意,您很可能希望匹配isDisplayed()isCompletelyDisplayed() 而不是withEffectiveVisibility(),因为后一种方法匹配在 Viewvisibility 属性上,而不是在屏幕上是否实际可见。
      【解决方案3】:

      遇到了同样的问题。我很幸运,因为我的ViewPager 中的视图层次结构可以很容易地被他们的兄弟姐妹识别,所以我能够使用hasSibling 匹配器来解决这个问题,如下所示:

      onView(
          allOf(
              hasSibling(withId(R.id.some_sibling)),
              withId(R.id.field_to_test)
          )
      ).perform(replaceText("123"));
      

      不是一个完美的解决方案,因为它可能有点脆弱,但就我而言,我认为这是一个可以接受的折衷方案。

      【讨论】:

        【解决方案4】:

        我遇到了类似的问题,我重用了按钮布局,它在层次结构异常中给了我一个匹配多个视图。

        所以我所做的简单工作是创建 2 个不同的屏幕并使用 2 种不同的方法来处理不同的文本。

        1. 退出屏幕:

          public WithdrawScreen clickWithdraw() {
              onView(allOf(withId(R.id.save_button), withText("Withdraw")))
                  .perform(click());
              return this; 
          }
          
        2. 存款屏幕:

          public DepositScreen clickDeposit() {
              onView(allOf(withId(R.id.save_button), withText("Deposit")))
                  .perform(click());
              return this;
          }
          

        在我的测试中,我创建了两个屏幕的新实例,并根据屏幕引用调用上述方法,这有点容易测试。

        WithdrawScreen withdrawInstance = new WithdrawScreen();
        withdrawInstance.clickWithdraw();
        
        DepositScreen depositInstance = new DepositScreen();
        depositInstance.clickDeposit();
        

        关键是他们使用相同的 id - R.id.save_button 作为按钮,我正在根据我们所在片段的可见性替换按钮的文本。

        希望对你有帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-07
          • 1970-01-01
          相关资源
          最近更新 更多