airbnb / epoxy

Epoxy is an Android library for building complex screens in a RecyclerView
https://goo.gl/eIK82p
Apache License 2.0
8.47k stars 731 forks source link

Ui Test Carousel inside Recyclerview #1009

Open Vignesh150493 opened 4 years ago

Vignesh150493 commented 4 years ago

@elihart Thanks for epoxy! One of the best I have come across :).

Apologies in advance, if this has already been answered, or if I have missed something fundamental. I am not well versed with Espresso. This is a question related to Ui testing carousel inside a EpoxyRecyclerview.

This is how my recyclerview is laid out. Item 0 Carousel Item 1 Item 2 ...

While testing this, I try to find the carousel by hardcoding the carousel position, which looks something like this,

onView(withId(parentRecyclerViewId))
        .perform(actionOnItemAtPosition<ViewHolder>(positionOfCarousel, RecyclerViewActions
            .actionOnItem<ViewHolder>(viewHolderMatcher, click())))

Now, I think we can agree that this is not a good approach as the position of the carousel might change, later, if we try to add more items on top of it. When this happens , my tests will break. One way to solve this would be to try to find the carousel by view id, but I am not sure if it is possible to add a view id to carousel?

Is there anyway this can be solved? Of course let me know if I missed something basic here. Thanks in advance!

eagskunst commented 4 years ago

Another way of accesing the carousel is like this:

onView( allOf(instanceOf(Carousel::class.java)) )

Vignesh150493 commented 4 years ago

@eagskunst Thanks for replying. Yes, maybe I could go with this, but with the limitation that, I am not going to have more than one carousel in my Recyclerview at any point, right?

eagskunst commented 4 years ago

@Vignesh150493 Yes.

Also, I think that at Airbnb, the UI test is done by screenshots, so I don't think they are supporting UI test soon.

A way to solve the issue is to wrap the Carousel inside a view group (like a FrameLayout), assign an ID an use it like a ModelView or a ViewHolder.

If you plan to have multiple carousel, maybe using withContentDescription(description) would be more useful. You can pass the contentDescription as an EpoxyAttribute.