Currently I am trying to test the views using RecyclerView. The app works great, but in the test, it doesn't, it couldn't find method of RecyclerView, the followings are the dependencies in the test file
androidTestCompile ('com.android.support.test.espresso:espresso-core:2.0') {
exclude group: 'javax.inject'
exclude group: 'com.google.code.findbugs'
exclude group: 'com.android.support', module: 'support-v4'
}
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.0') {
exclude group: 'javax.inject'
exclude group: 'com.google.guava'
exclude group: 'com.android.support', module: 'support-annotations'
exclude module: 'recyclerview-v7'
}
And I got errors when I was using RecyclerViewActions.actionOnItemAtPosition and it will call RecyclerView's scrollToPosition() method. But it complains that it couldn't find this method:
java.lang.NoSuchMethodError: android.support.v7.widget.RecyclerView.scrollToPosition
at android.support.test.espresso.contrib.RecyclerViewActions$ScrollToPositionViewAction.perform(RecyclerViewActions.java:397)
at android.support.test.espresso.contrib.RecyclerViewActions$ActionOnItemAtPositionViewAction.perform(RecyclerViewActions.java:277)
at android.support.test.espresso.ViewInteraction$1.run(ViewInteraction.java:144)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
....
I assume the problem is, since it works fine in the app, that in the test, it might use the older version than the app. And for test dependency, the version for recyclerView is 21.0.3 and app version is 22.2.0. However, after I change the app version of RecyclerView to 21.0.3 (same as in test), it still has same error.
Much appreciate any comments
Ok, after two days of searching, finally I found the solution. It has something to do with Proguard. It turns out that the RecyclerView is obfuscated by Android Proguard. Thats the reason why Espresso cannot find this method.
Just simply add
-keep class android.support.v7.widget.RecyclerView { *; }
in proguard-rules.text and then you are all set.
Related
I had several libraries conflict issues. That i resolved by adding
configurations {
all {
exclude module: 'httpclient'
exclude module: 'commons-logging'
exclude group: 'org.json', module: 'json'
exclude group: 'org.apache.httpcomponents'
exclude module: 'xmlParserAPIs'
exclude module: 'xpp3'
exclude module: 'opengl-api'
}
}
But still following error present. And i am unable to build signed apk.
I have tried project clean/rebuild option.
Error: android defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem (for example, for httpclient use HttpUrlConnection or okhttp instead), or repackaging the library using something like jarjar. [DuplicatePlatformClasses]
Thanks in advance for your help.
Problem
How to see which dependency is creating conflicts. It is same like shooting in dark.
Solution
Some AS plugin that will show you which projects dependency hierarchy. You can find where issue presents exactly and solve that.
Gradle View is an Android Studio plugin that you can install and show dependency hierarchy.
Methods Count is another plugin, it also shows dependency tree.
The error may be comes from different module but if issue is httpcomp... or xpp3 then
I just add these lines of code in app Gradle
dependencies {
......
configurations {
all*.exclude group: 'xpp3', module: 'xpp3'
implementation.exclude group: "org.apache.httpcomponents", module: "httpclient"
}
}
done
I'm receiving a runtime error No interface method trackUsage() in UsageTracker.java when the lines run in the Espresso test to scroll to a certain element in the RecyclerView list:
onView(withId(R.id.recyclerView)).perform(scrollTo(hasDescendant(withText(text))));
I'm using RecyclerViewActions for the scrollTo() method.
Here are my current configurations and gradle dependencies:
Android Studio 3.0 Canery 9
compileSdkVersion 25
buildToolsVersion "26.0.1"
junit:junit:4.12
com.android.support.test:runner:1.0.0
com.android.support.test:rules:1.0.0
com.android.support.test.espresso:espresso-contrib:2.2.2
com.android.support.test.espresso:espresso-core:2.2.2
Android Support Library: 25.3.1
Also, for each of the androidTestCompile's I'm using the following excludes:
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'support-annotations'
exclude module: 'recyclerview-v7'
Full error message: No interface method trackUsage(Ljava/lang/String;)V in class Landroid/support/test/internal/runner/tracker/UsageTracker; or its super classes (declaration of 'android.support.test.internal.runner.tracker.UsageTracker' appears in /data/app/adamhurwitz.github.io.doordashlite.test-2/base.apk)
I was experiencing the same issue with rules 1.0.0 and runner 1.0.0. Though I was able to solve it by just adding espresso-core 3.0.0. Which avoids the use of outdated versions such as suggested in Erics answer.
com.android.support.test:rules:1.0.0
com.android.support.test.runner:1.0.0
com.android.support.test.espresso:espresso-core:3.0.0
EDIT:
Meanwhile one should use the AndroidX libraries, the current versions as of 2021 / 12 are:
androidx.test:rules:1.4.0
androidx.test:runner:1.4.0
androidx.test:core:1.4.0
androidx.test.espresso:espresso-core:3.4.0
The up to date versions can in general be found on the Android Developers page.
I had the same problem. To fix it I changed the following dependencies from:
com.android.support.test:runner:1.0.0
com.android.support.test:rules:1.0.0
to:
com.android.support.test:runner:0.5
com.android.support.test:rules:0.5
UPDATE:
Michael's answer is better, don't use this outdated version anymore!
I'm trying to make a simple espresso test that will find the first item in
RecyclerView without specific label and click on it. To achieve this I added espresso-contrib to project like this:
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
// Necessary to avoid version conflicts
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'design'
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'appcompat-v7'
exclude group: 'com.android.support', module: 'support-annotations'
exclude module: 'recyclerview-v7'
}
and wrote the following expression in my test case:
onView(withId(R.id.sresults_list_recycler)).perform(RecyclerViewActions.actionOnHolderItem(new FirstNotSoldOutMatcher(), click()).atPosition(1));
Matcher works perfectly and RecyclerView got scrolled to the target item. But then I get 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.example-1/base.apk)
at android.support.test.espresso.contrib.RecyclerViewActions$ActionOnItemAtPositionViewAction.perform(RecyclerViewActions.java:288)
at android.support.test.espresso.contrib.RecyclerViewActions$ActionOnItemViewAction.perform(RecyclerViewActions.java:232)
at android.support.test.espresso.ViewInteraction$1.run(ViewInteraction.java:144)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
This looks strange to me. I read in Google documentation that findViewHolderForPosition method is deprecated now but it should still be there. I also have multidex enabled in the app but according to docs it is supported out of the box so shouldn't be a problem too.
Do you have any idea what can be wrong with this test?
Ok, in my case problem was in ProGuard shrinking unused methods. Disabling it for tests helped.
For future seekers - if you don't want to disable proguard for debug build adding this line to proguard config should help too:
-keepclasseswithmembers public class android.support.v7.widget.RecyclerView { *; }
Also, note that this rule should be added to the regular proguard file(the one of listed in proguardFiles) and not the test one(declared as testProguardFile)
You can combine #Bersh's answer and this answer to be more strict about what to keep:
-keep class android.support.v7.widget.RecyclerView {
public android.support.v7.widget.RecyclerView$ViewHolder findViewHolderForPosition(int);
}
There is no reason to keep the entire RecyclerView class.
Update:
Or for when you inevitably update to AndroidX:
-keep class androidx.recyclerview.widget.RecyclerView {
public androidx.recyclerview.widget.RecyclerView$ViewHolder findViewHolderForPosition(int);
}
I have upgraded to the latest API level 24 which is the latest API Level (at time of writhing) anyhow it caused this error message.
Error:Conflict with dependency 'com.android.support:support-v4'. Resolved versions for app (24.2.0) and test app (23.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
So How can I fix this?
Also this page the 2nd answer down gives a solution to the problem but if you want to include
com.android.support.test.espresso:espresso-contrib:2.2.2
in your then this will lead to 4 more similar error messages.
So How can I get rid of these 4 extra error messages?
Here are my Espresso build.gradle dependencies:
androidTestCompile "com.android.support:support-annotations:$SUPPORT_VERSION"
androidTestCompile "com.android.support.test.espresso:espresso-core:$ESPRESSO_VERSION"
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile "com.android.support.test.espresso:espresso-intents:$ESPRESSO_VERSION"
/**
* AccessibilityChecks
* CountingIdlingResource
* DrawerActions
* DrawerMatchers
* PickerActions (Time and Date picker)
* RecyclerViewActions
*/
androidTestCompile("com.android.support.test.espresso:espresso-contrib:$ESPRESSO_VERSION") {
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'support-v7'
exclude group: 'com.android.support', module: 'design'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
}
where:
ESPRESSO_VERSION = '2.2.2'
Check my project's build.gradle file if you still stuck: https://github.com/piotrek1543/LocalWeather/blob/master/app/build.gradle
Hope it will help
I found a solution (workaround)
If you click on the picture below you will note look at the picture below you will note that the error message
Error:Conflict with dependency 'com.android.support:support-v4'. Resolved versions for app (24.2.0) and test app (23.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
will be fixed with the line
configurations.all {resolutionStrategy.force "com.android.support:support-v4:23.1.0"}
Which is located in the dependencies area of the gradle file
Likewise the error message
Error:Conflict with dependency 'com.android.support:appcompat-v7'. Resolved versions for app (24.2.0) and test app (23.1.0) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
can be fixed with the line
configurations.all {resolutionStrategy.force "com.android.support:appcompat-v7:23.1.0"}
And so on and so fourth until all the errors are solved
p.s Don't forget to go here for the main solution (2nd and 3rd answer down
You can force the support library in your test using:
androidTestCompile 'com.android.support:support-v4:24.2.0'
I am using Junit4 and Espresso for my tests. I am facing a weird issue with espresso tests - when I call onView sometimes everything is executed like it is supposed to, but sometimes my test freezes and after 60 seconds I get something like this "android.support.test.espresso.AppNotIdleException: Looped for 63 iterations over 60 SECONDS. The following Idle Conditions failed ASYNC_TASKS_HAVE_IDLED"
For example :
onView(withId(R.id.zone_button_continue)).perform(click());
onView(withId(R.id.loginButton)).check(matches(isDisplayed()));
onView(withId(R.id.number)).check(matches(isDisplayed()));
onView(withId(R.id.password)).check(matches(isDisplayed()));
onView(withId(R.id.number)).perform(typeText(phoneNumber));
onView(withId(R.id.password)).perform(typeText(password));
onView(withId(R.id.loginButton)).perform(click());
everything gets executed correctly, except the last line - for some reason it can't find that loginButton, but it is there 100% percent. I can do
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.findViewById(R.id.loginButton).performClick();
}
});
and that works. I have similar problems throughout most of my activities - sometimes onView is working sometimes not.
What could cause such an inconsistency? I have been fighting with this issue for a while, and it makes my testing very frustrating and difficult. My conclusions this far is that something is wrong with my gradle dependencies or there is some kind of bug in my application that prevents espresso to work properly. But it is strange that in the example above everything with onView is working except last line and everything is happening in one activity and that makes me doubt that the bug is within my application.
Here are my gradle dependencies:
compile files('src/main/libs/guice-3.0-no_aop.jar')
compile files('src/main/libs/javax.inject-1.jar')
compile files('src/main/libs/roboguice-2.0.jar')
compile files('src/main/libs/junit-4.11.jar')
compile files('src/main/libs/hamcrest-core-1.3.jar')
compile files('src/main/libs/GeoLib.jar')
compile files('src/main/libs/GeoPolygons.jar')
compile files('src/main/libs/universal-image-loader-1.9.4.jar')
compile files('src/main/libs/javax.annotation-3.2-b06-sources.jar')
compile ('uk.co.chrisjenx:calligraphy:2.1.0'){
exclude group:'com.android.support'
}
compile 'com.squareup:otto:1.3.5'
compile ('com.google.android.gms:play-services:6.5.87'){
exclude group:'com.android.support'
}
compile 'com.android.support:support-annotations:22.2.1'
compile ('com.android.support:appcompat-v7:22.2.0'){
exclude group:'com.android.support'
}
compile ('com.android.support:support-v4:22.2.0'){
exclude group:'com.android.support', module:'support-annotations'
}
compile ('com.android.support:palette-v7:22.2.0'){
exclude group:'com.android.support'
}
compile 'com.google.code.findbugs:jsr305:2.0.1'
compile 'com.nineoldandroids:library:2.4.0'
compile 'pl.charmas.android:android-reactive-location:0.4#aar'
compile 'io.reactivex:rxjava:1.0.3'
compile files('src/main/libs/FlurryAnalytics-6.1.0.jar')
compile 'com.github.castorflex.smoothprogressbar:library:1.1.0'
// androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
androidTestCompile('com.android.support.test:runner:0.4.1') {
exclude group: 'com.android.support', module: 'support-annotations'
}
// Set this dependency to use JUnit 4 rules
androidTestCompile('com.android.support.test:rules:0.4.1') {
exclude group: 'com.android.support', module: 'support-annotations'
}
// Set this dependency to build and run Espresso tests
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.1') {
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestCompile('com.android.support.test.espresso:espresso-intents:2.2.1') {
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestCompile('com.android.support.test.espresso:espresso-web:2.2.1') {
// PackagingOptions modified to make this work
exclude group: 'com.android.support', module: 'support-annotations'
}
testCompile 'junit:junit:4.11'
testCompile ('org.mockito:mockito-core:1.9.5'){
exclude group: 'org.hamcrest'
}
compile 'org.mod4j.org.apache.commons:lang:2.1.0'
Please help me with this problem, I am completely out of ideas and stuck with it.
The easiest way to see why you get an AppNotIdleExceptionwith the message "The following Idle Conditions failed ASYNC_TASKS_HAVE_IDLED", is to:
Run the tests in debug mode in Android Studio
Wait until the tests hang
Before the (default) 60 seconds have passed, pause the tests
Look in the "Threads" list and see your threads named "AsyncTask #1" and so on. Expand the one being in state RUNNING. There you see what part of the code is keeping the app busy
This was the result for my case, so I had to disable the Facebook SDK for my tests to make them stable again:
Had the same problem, also a bug with facebook libraries.
Switched to a different emulated device and everything works normally!