Я не могу запустить свой тестовый фрагмент с помощью Koin

#android #kotlin #testing #koin

Вопрос:

Я пытаюсь выполнить тесты пользовательского интерфейса в своем приложении, но не могу запустить свой фрагмент. Я продолжаю получать эту ошибку «Исключение java.lang.RuntimeException: Не удается разрешить действие для: Намерение { действие=android.намерение.действие.ГЛАВНАЯ кошка=[android.намерение.категория.ПУСКОВАЯ УСТАНОВКА] cmp=com.пример.marvelproject/androidx.фрагмент.приложение.тестирование.FragmentScenario$Пустая фрагментация (имеет дополнительные функции) }»

Я попытался изменить реализацию androidTestImplementation («androidx.fragment:тестирование фрагментов:$fragment_version»), чтобы выполнить отладочную реализацию, но затем я получаю ошибку двоичного xml.

Как я могу это сделать? Я в полном отчаянии от этой штуки.

Ниже приведены мои файлы:

 plugins {  id 'com.android.application'  id 'kotlin-android'  id 'kotlin-kapt'  id 'androidx.navigation.safeargs'  id 'kotlin-parcelize'  id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' }   android {  compileSdk 30   defaultConfig {  applicationId "com.example.marvelproject"  minSdk 21  targetSdk 30  versionCode 1  versionName "1.0"  testInstrumentationRunner "com.example.marvelproject.KoinTestRunner"  }  testOptions {  animationsDisabled = 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'  }  dataBinding {  enabled true  } }  dependencies {   implementation 'androidx.core:core-ktx:1.3.2'  implementation 'androidx.appcompat:appcompat:1.3.1'  implementation 'com.google.android.material:material:1.4.0'  implementation 'androidx.constraintlayout:constraintlayout:2.1.1'  implementation 'androidx.legacy:legacy-support-v4:1.0.0'  kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"  implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'  implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")  implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")  implementation "androidx.fragment:fragment-ktx:$fragment_version"  //coroutines  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")  //fragment navigation  implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")  implementation("androidx.navigation:navigation-ui-ktx:$nav_version")  //retrofit  implementation 'com.squareup.retrofit2:converter-gson:2.6.0'  implementation "com.squareup.retrofit2:retrofit:$retrofit_version"  implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'  //glide  implementation 'com.github.bumptech.glide:glide:4.12.0'  kapt 'com.github.bumptech.glide:compiler:4.12.0'  //koin  implementation "io.insert-koin:koin-android:$koin_version"  implementation "io.insert-koin:koin-android-compat:$koin_version"    testImplementation 'junit:junit:4. '  testImplementation "io.mockk:mockk:$mockk_version"  testImplementation("com.squareup.okhttp3:mockwebserver:$mockwebserver_version")  testImplementation "androidx.arch.core:core-testing:$archTestingVersion"  testImplementation "org.robolectric:robolectric:$robolectricVersion"  testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"  androidTestImplementation 'androidx.test.ext:junit:1.1.3'  androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'  androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'  androidTestImplementation "androidx.test:core-ktx:1.4.0"  androidTestImplementation 'androidx.test:rules:1.4.0'  androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")  androidTestImplementation ("androidx.fragment:fragment-testing:$fragment_version") }  

Основной манифест

 lt;?xml version="1.0" encoding="utf-8"?gt; lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"  package="com.example.marvelproject"gt;   lt;uses-permission android:name="android.permission.INTERNET"/gt;   lt;application  android:name=".BaseApplication"  android:allowBackup="true"  android:usesCleartextTraffic="true"  android:icon="@mipmap/ic_launcher"  android:label="@string/app_name"  android:roundIcon="@mipmap/ic_launcher_round"  android:supportsRtl="true"  android:theme="@style/Theme.MarvelProject"gt;   lt;activity  android:name=".MainActivity"  android:exported="true"  android:windowSoftInputMode="adjustNothing"  gt;  lt;intent-filtergt;  lt;action android:name="android.intent.action.MAIN" /gt;   lt;category android:name="android.intent.category.LAUNCHER" /gt;  lt;/intent-filtergt;  lt;/activitygt;  lt;/applicationgt;  lt;/manifestgt;  

Debug Manifest

 lt;?xml version="1.0" encoding="utf-8"?gt; lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"  package="com.example.marvelproject"gt;   lt;applicationgt;  lt;activity android:name="androidx.fragment.app.FragmentActivity"  android:exported="false"gt;  lt;/activitygt;  lt;/applicationgt;  lt;/manifestgt;  
 class KoinTestApp : Application() {  override fun onCreate() {  super.onCreate()  startKoin {  androidContext(this@KoinTestApp)  modules(emptyList())  }  }   internal fun injectModule(module: Module){  loadKoinModules(module)  } }  
 class KoinTestRunner: AndroidJUnitRunner() {  override fun newApplication(  cl: ClassLoader?, className: String?, context: Context?  ): Application {  return super.newApplication(  cl, KoinTestApp::class.java.name, context  )  } }  
  abstract class FragmentTestRulelt;F: Fragmentgt;:  ActivityTestRulelt;FragmentActivitygt;(FragmentActivity::class.java, true) {  override fun afterActivityLaunched() {  super.afterActivityLaunched()   activity.runOnUiThread {  val fm = activity.supportFragmentManager  val transaction = fm.beginTransaction()  transaction.replace(android.R.id.content, createFragment()).commit()  }  }   override fun beforeActivityLaunched() {  super.beforeActivityLaunched()  val application =  InstrumentationRegistry.getInstrumentation().targetContext  .applicationContext as KoinTestApp  application.injectModule(getModule())  }   protected abstract fun createFragment(): F   protected abstract fun getModule(): Module   fun launch() {  launchActivity(Intent())  } }  fun lt;F: Fragmentgt; createRule(fragment: F, module: Module): FragmentTestRulelt;Fgt; =  object: FragmentTestRulelt;Fgt;() {  override fun createFragment(): F = fragment  override fun getModule(): Module = module  }  
 class HomeFragmentTest {    private val modules = module {  val repository = FakeRepositoryImpl()  viewModel{MarvelViewModel(repository)}  }    @Before  fun setup(){  loadKoinModules(modules)  launchFragmentInContainerlt;HomeFragmentgt;()  }   @Test  fun shouldDisplayRecyclerViewResults() { // onView(withId(R.id.tv_nome)).check(matches(isDisplayed()))  }  }