Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing recyclerView with Espresso, how to perform click or make assertions

Lately I need to test RecyclerView and I am having a lot of trouble to do anything with it.

First of all I came to know that Espresso is already "supporting" RecyclerViews by providing us RecyclerViewActions located in espresso-contrib. So I've decided to use it and my dependencies looks like that:

dependencies {

    androidTestCompile 'junit:junit:4.12'
    androidTestCompile 'com.squareup.spoon:spoon-client:1.2.1'
    androidTestCompile 'com.jraska:falcon-spoon-compat:0.3.1'
    androidTestCompile 'com.android.support:support-annotations:23.1.1'

    androidTestCompile 'com.android.support.test:runner:0.4.1'
    androidTestCompile 'com.android.support.test:rules:0.4.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.1'

    androidTestCompile "org.mockito:mockito-core:1.10.19"
    androidTestCompile "com.google.dexmaker:dexmaker:1.2"
    androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
}

But as only I try to run my test after changing espresso-core to espresso-contrib. I can see this error:

Test running failed: Instrumentation run failed due to 'java.lang.IncompatibleClassChangeError'

I tried to google it out. I saw many topics where people were giving responses like this one. So I excluded appcompat, supportv4 and recyclerview-v7. Like that:

   androidTestCompile ('com.android.support.test.espresso:espresso-contrib:2.2.1') {
        exclude group: 'com.android.support', module: 'appcompat'
        exclude group: 'com.android.support', module: 'support-v4'
        exclude module: 'recyclerview-v7'
    }

And tests start but... I can't use any RecyclerViewActions. Because there is no methods after excluding recyclerview-v7 what is recommended almost everywhere I saw on the web. When I try to use - RecyclerViewActions.actionOnItemAtPosition - the method which is core for me I get this error:

java.lang.NoSuchMethodError: No virtual method findViewHolderForPosition(I)Landroid/support/v7/widget/RecyclerView$ViewHolder; in class Landroid/support/v7/widget/RecyclerView; or its super classes (declaration of 'android.support.v7.widget.RecyclerView' appears in /data/app/com.myapp.debug1-1/base.apk)
at android.support.test.espresso.contrib.RecyclerViewActions$ActionOnItemAtPositionViewAction.perform(RecyclerViewActions.java:288)
at android.support.test.espresso.ViewInteraction$1.run(ViewInteraction.java:144)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

So I'd rather have this recyclerview-v7 instead of excluding it. I modify my espresso-contrib import to:

 androidTestCompile ('com.android.support.test.espresso:espresso-contrib:2.2.1') {
        exclude group: 'com.android.support', module: 'appcompat'
        exclude group: 'com.android.support', module: 'support-v4'
    }

Test run again but... I get error somewhere during tests:

android.view.InflateException: Binary XML file line #36: Error inflating class android.support.design.widget.NavigationView

So I am using most recent libs in my gradle:

 compile 'com.android.support:appcompat-v7:23.1.1'
 compile 'com.android.support:support-v13:23.1.1'
 compile 'com.android.support:cardview-v7:23.1.1'
 compile 'com.android.support:design:23.1.1'

And NavigationView is using newest RecyclerView 23.1.1. I try to find what is wrong so I display dependencies of espresso-contrib by using ./gradlew app:dependencies in console and I can see:

 +--- com.android.support.test.espresso:espresso-contrib:2.2.1
|    +--- com.android.support.test.espresso:espresso-core:2.2.1
|    |    +--- com.squareup:javawriter:2.1.1
|    |    +--- com.android.support.test:runner:0.4.1 (*)
|    |    +--- com.android.support.test:rules:0.4.1 (*)
|    |    +--- javax.inject:javax.inject:1
|    |    +--- org.hamcrest:hamcrest-library:1.3
|    |    |    \--- org.hamcrest:hamcrest-core:1.3
|    |    +--- org.hamcrest:hamcrest-integration:1.3
|    |    |    \--- org.hamcrest:hamcrest-library:1.3 (*)
|    |    +--- com.google.code.findbugs:jsr305:2.0.1
|    |    +--- javax.annotation:javax.annotation-api:1.2
|    |    \--- com.android.support.test.espresso:espresso-idling-resource:2.2.1
|    +--- com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.0
|    |    \--- org.hamcrest:hamcrest-core:1.3
|    \--- com.android.support:recyclerview-v7:23.0.1
|         \--- com.android.support:support-annotations:23.0.1 -> 23.1.1

Okay so espresso-contrib-2.2.1 which is newest one is using com.android.support:recyclerview-v7:23.0.1 - not most recent version of recyclerView and it is causing an error. I decide to update it inside espresso-contrib by adding:

 androidTestCompile 'com.android.support:recyclerview-v7:23.1.1'

I use app:dependencies again and I can see change:

\--- com.android.support:recyclerview-v7:23.0.1 -> 23.1.1 (*)

I start tests again. And I don't get error with NavigationView anymore - I think it's solved but... another error appears:

android.view.InflateException: Binary XML file line #21: Error inflating class android.support.v7.widget.Toolbar

And now I am a bit out of ideas. When you look at the dependencies of espresso-contrib it is not using anything that might use toolbar in my opinion. Toolbar is part of appcompat-v7 so I try to add it the same way as I upgraded recyclerView to newest version. So I add:

androidTestCompile 'com.android.support:appcompat-v7:23.1.1'

But it doesn't help me. And I am stuck.

Did you face those problems? Do you have any workaround how to click on recyclerView? How to check if item in recyclerView has text or something like that? All of solutions I've found on the web are using method: findViewHolderForPosition which I can't use after excluding recyclerview-v7 module. Like :

https://github.com/dannyroa/espresso-samples/tree/master/RecyclerView/app/src/androidTest/java/com/dannyroa/espresso_samples/recyclerview

or

https://gist.github.com/chemouna/00b10369eb1d5b00401b

or more.

 

like image 451
F1sher Avatar asked Dec 08 '15 15:12

F1sher


People also ask

How do you scroll with espresso?

You can use SWIPE to scroll to the bottom of the screen: Espresso. onView(ViewMatchers. withId(R.

How do I get Textview espresso from text?

The basic idea is to use a method with an internal ViewAction that retrieves the text in its perform method. Anonymous classes can only access final fields, so we cannot just let it set a local variable of getText() , but instead an array of String is used to get the string out of the ViewAction .


1 Answers

Problem with Toolbar is caused by the fact, some of libs I use in my app.gradle file doesn't have most recent RecyclerView so I needed to add also:

compile 'com.android.support:appcompat-v7:23.1.1'

Problem with java.lang.NoSuchMethodError is on my side. ProGuard config was deleting few methods.

like image 190
F1sher Avatar answered Oct 27 '22 12:10

F1sher