android / android/android-test
espresso-contrib makes ActivityScenarioRule trigger ClassNotFoundException
- Dominant language
- Java
- Stars
- 1.2k
- Forks
- 342
- Avg merge
- 11h 29m
- Merged PRs (30d)
- 2
Description
### Description
If `espresso-contrib` is added to `build.gradle`, then adding an `ActivityScenarioRule` to a simple androidTest causes a fatal ClassNotFoundException.
### Steps to Reproduce
1. Start with a simple Android Studio project. I used the "Blank Activity" template with kotlin and SDK 27.
2. Add to `build.gradle`:
`androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'`
3. Add a new member variable to an androidTest, e.g. `ExampleInstrumentedTest`:
```
@get:Rule
val rule = ActivityScenarioRule(MainActivity::class.java)
```
4. Launch an AVD (I used Android 11.0 (Google APIs) on Pixel 5)
5. Run the test
### Expected Results
The test should pass.
### Actual Results
The test hangs and eventually terminates. Immediately after the test starts, logcat reports a crash:
```
2021-09-25 02:19:35.656 10153-10153/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.foo.ruletest.test, PID: 10153
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/test/internal/util/Checks;
at androidx.test.core.app.InstrumentationActivityInvoker$BootstrapActivity.onResume(InstrumentationActivityInvoker.java:169)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1456)
at android.app.Activity.performResume(Activity.java:8135)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4434)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4476)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.test.internal.util.Checks" on path: DexPathList[[zip file "/data/app/~~dPOmzOwzgsQWBjEGt2CgBA==/com.foo.ruletest.test-3LocvMQ2WLgtGbjdq_FpWA==/base.apk"],nativeLibraryDirectories=[/data/app/~~dPOmzOwzgsQWBjEGt2CgBA==/com.foo.ruletest.test-3LocvMQ2WLgtGbjdq_FpWA==/lib/x86_64, /system/lib64, /system_ext/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at androidx.test.core.app.InstrumentationActivityInvoker$BootstrapActivity.onResume(InstrumentationActivityInvoker.java:169)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1456)
at android.app.Activity.performResume(Activity.java:8135)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4434)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4476)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
```
### AndroidX Test and Android OS Versions
```
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
testImplementation 'junit:junit:4.13.2'
implementation 'androidx.test.espresso:espresso-contrib:3.4.0'
```
Android 11.0 (Google APIs) on virtual Pixel 5
### Other
This doesn't seem to repro if espresso-contrib is used as `androidTestImplementation` instead of as `implementation`. But a number of examples I've found use it as `implementation`.
I ran into this while trying to test `SettingsFragment`. I found a few similar (unsolved) reports:
* #964
* [Jetpack compose, Instrumental tests: java.lang.ClassNotFoundException: Didn't find class "androidx.test.internal.util.Checks"](https://stackoverflow.com/questions/68800881/jetpack-compose-instrumental-tests-java-lang-classnotfoundexception-didnt-fi)
Contributor guide
Research direction
Start with the dependency declarations in build.gradle and the ExampleInstrumentedTest member using ActivityScenarioRule. Reproduce the failure on the stated Android 11 AVD and inspect logcat for the missing androidx.test.internal.util.Checks class. Done means the espresso-contrib setup no longer causes the ClassNotFoundException and the instrumentation test passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, java, kotlin
- Domain
- mobile, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100