Issue
I have a viewpager which has at least 4 elements in it but it is dynamic and can have more then 4. I want to test that I am able to swipe the pager at least 4 times. The test is testing that the viewPager has at least 4 elements that I can swipe to. How can I accomplish this. here is what I have so far:
int numOfPages = 4;
do {
onView(withId(R.id.pager)), matches(isDisplayed());
onView(withId(R.id.pager))
.perform(swipeLeft());
numOfPages--;
} while (numOfPages > 0);
but all this is doing is swiping left at least 4 times. if I change numOfPages to 15 it just tries to swipe 15 times without throwing any error. so how can I know test a successful swipe? The Fragments in the viewpager are not clickable, they only show images.
Solution
If all you care is the number of pages, then writing a ViewMatcher that asserts that there are n or more than n pages is trivial:
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)
}
}
}
If you actually want to know if the pager is "swipeable" at least 4 times, we can add another matcher that asserts that the pager is at n page after each swipe:
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
}
}
}
The usage is the following:
onView(withId(R.id.pager)).check(matches(withNumberOfPages(Matchers.greaterThan(4))))
&&
onView(withId(R.id.pager)).check(matches(withSelectedPage(1)))
But another philosophical question here is does it actually test anything? Maybe. But depending on the actual business needs it might not actually be helpful.
How does a user know that they swiped successfully? They probably see something on the screen. The idea of espresso is to approach testing in a similar fashion. And if there is an actual interest in what's on the page it all boils down to the hermetic environment for testing. If you are not in control of data that the test receives, you are not testing much. If you could mock the data coming in, then the vewpager will always be set to the same number of the pages and you will know what each of them contains. This will make your tests more self-contained, deterministic and provide actual value.
Answered By - Be_Negative
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.