'Unable to run Android Espresso tests. The project uses Hilt Dependency Injection and Navigation Components
I am trying to run the following Espresso test. I have Android Hilt dependency injection setup in my project and its working well in the application but am facing issues running UI tests.
I also have a project library which is using Hilt aswell.
Getting the following Exception:
Process: com.muddassir.myapp, PID: 15570
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/test/internal/platform/tracker/UsageTracker;
at java.lang.Class.newInstance(Native Method)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6952)
at android.app.ActivityThread.access$1500(ActivityThread.java:272)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2055)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8019)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.test.internal.platform.tracker.UsageTracker" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/system/framework/android.test.mock.jar", zip file "/data/app/com.muddassir.myapp.test-sXVdfWq9tpbgNg9sbalPuAase.apk", zip file "/data/app/com.cs.stackoverflow-hHsBjEoBRyEmFRYwawGgqA==/base.apk"],nativeLibraryDirectories=[/data/app/com.cs.stackoverflow.test-sXVdfWq9tpbgNg9sbalPuA==/lib/arm, /data/app/com.cs.stackoverflow-hHsBjEoBRyEmFRYwawGgqA==/lib/arm, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
My test is as follows
package com.muddassir.myapp.ui.activity
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.*
import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.filters.LargeTest
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import com.cs.stackoverflow.R
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.Matchers.allOf
import org.hamcrest.TypeSafeMatcher
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.internal.runners.JUnit4ClassRunner
import org.junit.runner.RunWith
@LargeTest
@HiltAndroidTest
@RunWith(AndroidJUnit4ClassRunner::class)
class ParameterTest {
@get:Rule()
var hiltRule = HiltAndroidRule(this)
@get:Rule
val activityRule = AndroidJUnit4ClassRunner(MainActivity::class.java)
@Before
fun init() {
hiltRule.inject()
}
@Test
fun parameterTest() {
val recyclerView = onView(
allOf(
withId(R.id.questionsRv),
childAtPosition(
withId(R.id.swipeToRefreshL),
0
)
)
)
recyclerView.perform(actionOnItemAtPosition<ViewHolder>(0, click()))
}
private fun childAtPosition(
parentMatcher: Matcher<View>, position: Int
): Matcher<View> {
return object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description) {
description.appendText("Child at position $position in parent ")
parentMatcher.describeTo(description)
}
public override fun matchesSafely(view: View): Boolean {
val parent = view.parent
return parent is ViewGroup && parentMatcher.matches(parent)
&& view == parent.getChildAt(position)
}
}
}
}
lib/build.gradle
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "com.cs.myapp_lib.HiltTestRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
def test_version = "1.3.1-alpha03"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
// Retrofit
def retrofit = "2.9.0"
api "com.squareup.retrofit2:retrofit:$retrofit"
api "com.squareup.retrofit2:converter-gson:$retrofit"
api "com.squareup.retrofit2:converter-scalars:$retrofit"
api "com.squareup.retrofit2:adapter-rxjava2:$retrofit"
api 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2'
// Utilities
api 'com.github.muddassir235:kmacros:1.10'
def room = "2.2.6"
api "androidx.room:room-runtime:$room"
api "androidx.room:room-ktx:$room"
kapt "androidx.room:room-compiler:$room"
// Dependency Injection through HILT
def hilt_version = '2.31.2-alpha'
api "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
// ...with Kotlin.
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
def hilt_view_models = '1.0.0-alpha03'
api "androidx.hilt:hilt-lifecycle-viewmodel:$hilt_view_models"
kapt "androidx.hilt:hilt-compiler:$hilt_view_models"
// Libraries for tests
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.3.1-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-web:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.4.0-alpha03'
androidTestImplementation 'androidx.test:runner:1.3.1-alpha03'
androidTestImplementation "androidx.test:core-ktx:$test_version"
androidTestImplementation 'androidx.test:rules:1.3.1-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0-alpha03'
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
}
app/build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
id 'androidx.navigation.safeargs.kotlin'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.cs.stackoverflow"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "com.muddassir.myapp.HiltTestRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation project(':stackoverflow_lib')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
// Dependency Injection through HILT
def hilt_version = '2.31.2-alpha'
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
// ...with Kotlin.
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
// ...with Java.
// androidTestAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.28-alpha'
def hilt_view_models = '1.0.0-alpha03'
implementation "androidx.hilt:hilt-lifecycle-viewmodel:$hilt_view_models"
kapt "androidx.hilt:hilt-compiler:$hilt_view_models"
// Libraries for tests
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
def fragment_version = '1.3.0-rc02'
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
def test_version = "1.3.1-alpha03"
def nav_version = '2.3.3'
// Kotlin
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-web:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.4.0-alpha03'
androidTestImplementation 'androidx.test:runner:1.3.1-alpha03'
androidTestImplementation 'androidx.test:rules:1.3.1-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0-alpha03'
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
androidTestImplementation "androidx.test:core-ktx:$test_version"
androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
}
Project build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.4.30"
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.28-alpha'
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.3"
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Solution 1:[1]
Use the stable versions of the test runner and rules 1.3.0 or 1.3.1-alpha02
implementation "androidx.test:runner:1.3.0"
implementation "androidx.test:rules:1.3.0"
Solution 2:[2]
I'm facing the same. If we use hilt test with custom runner class then we got issues in runner class.
testInstrumentationRunner "com.example.testing.HiltTestRunner"
so while using hilt, the manual test cases would be better.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
