Android Studio において、「test は実行できるが androidTest の実行ができない」という症状に陥りました。
今回はその解決方法についてメモしておこうと思います。
[目次]
環境
- compose_version = '1.0.1' - targetSdk 31 - kotlinCompilerVersion '1.5.21'
今回は環境設定に関する記事なので、以下に gradle ファイルを書き出しておこうと思います。
プロジェクトレベルの build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { compose_version = '1.0.1' } repositories { google() mavenCentral() } dependencies { classpath "com.android.tools.build:gradle:7.0.2" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21" classpath "com.google.dagger:hilt-android-gradle-plugin:2.38.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } task clean(type: Delete) { delete rootProject.buildDir }
アプリケーションレベルの build.gradle
plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-kapt' id 'dagger.hilt.android.plugin' } android { compileSdk 31 defaultConfig { applicationId "io.kokoichi.sample.sakamichiapp" minSdk 23 targetSdk 31 versionCode 1 versionName "1.0" buildConfigField("String", "API_KEY", API_KEY) testInstrumentationRunner "io.kokoichi.sample.sakamichiapp.HiltTestRunner" vectorDrawables { useSupportLibrary true } } 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' useIR = true } buildFeatures { compose true } composeOptions { kotlinCompilerExtensionVersion compose_version kotlinCompilerVersion '1.5.21' } packagingOptions { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' } } } dependencies { implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.material:material:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' implementation 'androidx.activity:activity-compose:1.3.1' implementation 'androidx.test:runner:1.4.0' testImplementation 'junit:junit:4.13.2' debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" // Compose dependencies implementation "androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07" implementation "androidx.navigation:navigation-compose:2.4.0-alpha08" implementation "com.google.accompanist:accompanist-flowlayout:0.17.0" // Retrofit def retrofit_version = '2.9.0' implementation "com.squareup.retrofit2:retrofit:$retrofit_version" implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' implementation "com.squareup.okhttp3:okhttp:4.9.0" implementation "com.squareup.okhttp3:logging-interceptor:4.9.0" implementation "com.squareup.retrofit2:retrofit-mock:$retrofit_version" // Timber implementation 'com.jakewharton.timber:timber:4.7.1' // Coroutines implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3' // Coroutine Lifecycle Scopes implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1" implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0" // Coil implementation("io.coil-kt:coil-compose:1.4.0") //Dagger - Hilt implementation "com.google.dagger:hilt-android:2.38.1" kapt "com.google.dagger:hilt-android-compiler:2.37" implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03" kapt "androidx.hilt:hilt-compiler:1.0.0" implementation 'androidx.hilt:hilt-navigation-compose:1.0.0-alpha03' androidTestImplementation 'com.google.dagger:hilt-android-testing:2.37' kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.37' // Local Unit Tests implementation "androidx.test:core:1.4.0" testImplementation "junit:junit:4.13.2" testImplementation "org.hamcrest:hamcrest-all:1.3" testImplementation "androidx.arch.core:core-testing:2.1.0" testImplementation "org.robolectric:robolectric:4.5.1" testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.0" testImplementation "com.google.truth:truth:1.1.3" testImplementation "com.squareup.okhttp3:mockwebserver:4.9.1" testImplementation "io.mockk:mockk:1.12.0" testImplementation "org.robolectric:robolectric:4.5.1" testImplementation("org.assertj:assertj-core:3.21.0") // Instrumented Unit Tests androidTestImplementation "junit:junit:4.13.2" androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.0" androidTestImplementation "androidx.arch.core:core-testing:2.1.0" androidTestImplementation "com.google.truth:truth:1.1.3" androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test:core-ktx:1.4.0' androidTestImplementation "com.squareup.okhttp3:mockwebserver:4.9.1" androidTestImplementation "io.mockk:mockk-android:1.12.0" androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" // Action bar helper implementation "com.google.accompanist:accompanist-systemuicontroller:0.17.0" }
症状
- test は実行できる
- androidTest の実行ができない
- 最初から用意されてるテストすら実行できない
エラーキーワード
- Could not resolve all files for configuration - app:debugAndroidTestRuntimeClasspath - Could not resolve junit:junit:4.13.2. - Cannot find a version of 'junit:junit' that satisfies the version constraints:
エラーメッセージ
androidTest 実行時のエラーメッセージを抜粋して記述します。
junit:junit:4.13.
と junit:junit:4.12.
に依存するパッケージがあり、その読み込みの衝突が起こった結果、どちらも読み込めてないのかな、と思いました。
4: Task failed with an exception. ----------- * What went wrong: Execution failed for task ':app:mergeDebugAndroidTestNativeLibs'. > Could not resolve all files for configuration ':app:debugAndroidTestRuntimeClasspath'. > Could not resolve junit:junit:4.13.2. Required by: project :app project :app > com.google.truth:truth:1.1.3 > Cannot find a version of 'junit:junit' that satisfies the version constraints: Dependency path 'Sakamichi app:app:unspecified' --> 'junit:junit:4.13.2' ... > Could not resolve junit:junit:{strictly 4.12}. Required by: project :app > Cannot find a version of 'junit:junit' that satisfies the version constraints: Dependency path 'Sakamichi app:app:unspecified' --> 'junit:junit:4.13.2' Constraint path 'Sakamichi app:app:unspecified' --> 'junit:junit:{strictly 4.12}' because of the following reason: debugRuntimeClasspath uses version 4.12 Dependency path 'Sakamichi app:app:unspecified' --> 'com.google.dagger:hilt-android-testing:2.37' (runtime) --> 'junit:junit:4.13' Dependency path 'Sakamichi app:app:unspecified' --> 'androidx.arch.core:core-testing:2.1.0' (runtime) --> 'junit:junit:4.12' Dependency path 'Sakamichi app:app:unspecified' --> 'com.google.truth:truth:1.1.3' (runtime) --> 'junit:junit:4.13.2' Dependency path 'Sakamichi app:app:unspecified' --> 'androidx.test.ext:junit:1.1.3' (runtime) --> 'junit:junit:4.12' Dependency path 'Sakamichi app:app:unspecified' --> 'com.squareup.okhttp3:mockwebserver:4.9.1' (runtimeElements) --> 'junit:junit:4.13' Dependency path 'Sakamichi app:app:unspecified' --> 'androidx.compose.ui:ui-test-junit4:1.0.1' (releaseVariantReleaseRuntimePublication) --> 'junit:junit:4.12' Dependency path 'Sakamichi app:app:unspecified' --> 'androidx.test.espresso:espresso-core:3.4.0' (runtime) --> 'androidx.test:runner:1.4.0' (runtime) --> 'junit:junit:4.12' > Could not resolve junit:junit:4.13. Required by: project :app > com.google.dagger:hilt-android-testing:2.37 project :app > com.squareup.okhttp3:mockwebserver:4.9.1 > Cannot find a version of 'junit:junit' that satisfies the version constraints: Dependency path 'Sakamichi app:app:unspecified' --> 'junit:junit:4.13.2' Constraint path 'Sakamichi app:app:unspecified' --> 'junit:junit:{strictly 4.12}' because of the following reason: debugRuntimeClasspath uses version 4.12 Dependency path 'Sakamichi app:app:unspecified' --> 'com.google.dagger:hilt-android-testing:2.37' (runtime) --> 'junit:junit:4.13' Dependency path 'Sakamichi app:app:unspecified' --> 'androidx.arch.core:core-testing:2.1.0' (runtime) --> 'junit:junit:4.12' Dependency path 'Sakamichi app:app:unspecified' --> 'com.google.truth:truth:1.1.3' (runtime) --> 'junit:junit:4.13.2' Dependency path 'Sakamichi app:app:unspecified' --> 'androidx.test.ext:junit:1.1.3' (runtime) --> 'junit:junit:4.12' Dependency path 'Sakamichi app:app:unspecified' --> 'com.squareup.okhttp3:mockwebserver:4.9.1' (runtimeElements) --> 'junit:junit:4.13' Dependency path 'Sakamichi app:app:unspecified' --> 'androidx.compose.ui:ui-test-junit4:1.0.1' (releaseVariantReleaseRuntimePublication) --> 'junit:junit:4.12' Dependency path 'Sakamichi app:app:unspecified' --> 'androidx.test.espresso:espresso-core:3.4.0' (runtime) --> 'androidx.test:runner:1.4.0' (runtime) --> 'junit:junit:4.12' ...
解決策
build.gralde
の中に、次のような設定(configurations)を記述します。
依存関係の衝突がが起きた時に、無理矢理使うバージョンを指定するためのものだと理解しています。(新しいものの方がいいだろう、というノリで 4.13.2 の方を選択しました。)
android { packagingOptions { ... } configurations.all { resolutionStrategy { force 'junit:junit:4.13.2' } } }
参考サイト
おわりに
今回は androidTest を走らせようとした際に起こった、依存性の衝突の回避方法について紹介しました。
gradle の部分は毎回コピペで済ませてしまっているのでいつか理解したいと思います。