代码之家  ›  专栏  ›  技术社区  ›  j2emanue

Android Espresso-如何确认swipeLeft()实际刷卡?

  •  2
  • j2emanue  · 技术社区  · 8 年前

    我有一个viewpager,其中至少有4个元素,但它是动态的,可以有4个以上的元素。我想测试一下我是否能够至少滑动寻呼机4次。测试是测试viewPager是否至少有4个元素可以滑动。我怎样才能做到这一点。以下是我目前掌握的情况:

     int numOfPages = 4;
            do {
                onView(withId(R.id.pager)), matches(isDisplayed());
                onView(withId(R.id.pager))
                        .perform(swipeLeft());
                numOfPages--;
            } while (numOfPages > 0);
    

    但这所做的只是向左滑动至少4次。如果我将numOfPages更改为15,它只会尝试刷15次而不会抛出任何错误。那么,我如何知道测试是否成功刷卡呢?viewpager中的片段不可单击,它们只显示图像。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Be_Negative    8 年前

    如果您只关心页面的数量,那么编写一个ViewMatcher来断言有n个或多个页面是微不足道的:

    fun withNumberOfPages(numberOfPages: Matcher<Int>): Matcher<View> {
    
        return object : BoundedMatcher<View, ViewPager>(ViewPager::class.java) {
            override fun describeTo(description: Description) {
                description.appendText("with ")
                numberOfPages.describeTo(description)
                description.appendText("number of pages")
    
            }
    
            override fun matchesSafely(viewPager: ViewPager): Boolean {
                return numberOfPages.matches(viewPager.adapter?.count ?: -1)
            }
        }
    }
    

    如果您确实想知道寻呼机是否至少可“滑动”4次,我们可以添加另一个匹配器,该匹配器在每次滑动后断言寻呼机位于n页:

    fun withSelectedPage(selection: Int): Matcher<View> {
        return object : BoundedMatcher<View, ViewPager>(ViewPager::class.java) {
            private var actualSelection = -1
    
            override fun describeTo(description: Description) {
                if (actualSelection != -1) {
                    description.appendText("with $selection page selected")
                    description.appendText("\n But page $actualSelection was selected")
                }
            }
    
            override fun matchesSafely(viewPager: ViewPager): Boolean {
                actualSelection = viewPager.currentItem
                return selection == actualSelection
            }
        }
    }
    

    用法如下:

    onView(withId(R.id.pager)).check(matches(withNumberOfPages(Matchers.greaterThan(4))))
    

    &&

    onView(withId(R.id.pager)).check(matches(withSelectedPage(1)))
    

    但另一个哲学问题是,它真的测试了什么吗?大概但根据实际的业务需求,这实际上可能没有帮助。

    用户如何知道他们已成功刷卡?他们可能在屏幕上看到了什么。浓缩咖啡的想法是以类似的方式进行测试。如果对页面上的内容有真正的兴趣,那么可以归结为测试的密封环境。如果您不能控制测试接收到的数据,那么您就没有进行太多测试。如果可以模拟传入的数据,那么vewpager将始终设置为相同的页数,并且您将知道每个页数包含哪些内容。这将使您的测试更加独立、确定,并提供实际价值。

        2
  •  1
  •   jeprubio    8 年前

    您可以检查viewPager。getCurrentItem()是您期望的自定义匹配器:

    @Test
    public void swipeFirstPages() {
      int numPages = 4;
      for (int i = 0; i < numPages; i++) {
        // Check the ViewPager is in page i
        onView(withId(R.id.pager)).check(matches(inPage(i)));
    
        if (i < numPages - 1) { // perform swipe if not on last page
          onView(withId(R.id.pager)).perform(swipeLeft());
          SystemClock.sleep(800);
        }
      }
    }
    

    以及在 inPage公司 匹配器:

    /**
     * Returns a matcher that matches {@link ViewPager}s based on currentItem property value.
     *
     * @param page {@link Matcher} of ViewPager's currentItem
     */
    @NonNull
    public static Matcher<View> inPage(final int page) {
    
      return new BoundedMatcher<View, ViewPager>(ViewPager.class) {
    
        @Override
        public void describeTo(final Description description) {
          description.appendText("in page: " + page);
        }
    
        @Override
        public boolean matchesSafely(final ViewPager viewPager) {
          return viewPager.getCurrentItem() == page;
        }
      };
    }
    

    如果你想避开系统时钟。执行每次刷卡后都可以使用 ViewPagerIdlingResource .