Taking yet another shot at compose multiplatform t...
# compose
a
Taking yet another shot at compose multiplatform testing and my connectedTests aren't running. This is what gradle prints out
Copy code
> Task :academia-compose:connectedDebugAndroidTest
Starting 0 tests on Medium_Phone_API_35(AVD) - 15
I have managed to make them run in ios and desktop, but still failing on Android
I believe i have followed the compose multiplatform test guide but i still get the error above. My
build.gradle.kts
looks like this
Copy code
android {
    defaultConfig {
        minSdk = 25 // because of the coil dependency has this as it's min sdk

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
}
// ... some other stuffs
kotlin {
    androidTarget {
        compilations.all {
            compileTaskProvider {
                compilerOptions.jvmTarget = JvmTarget.JVM_17
            }
        }
        @OptIn(ExperimentalKotlinGradlePluginApi::class)
        instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree.test)

        dependencies {
            androidTestImplementation("androidx.compose.ui:ui-test-junit4-android:1.7.1")
            debugImplementation("androidx.compose.ui:ui-test-manifest:1.7.1")
        }
    }   
}
What am I missing??
k
I'm pretty sure that you should put these dependencies inside android block at the end of the file
Copy code
android {
    ...
    dependencies {
        debugImplementation(compose.uiTooling)
        androidTestImplementation("androidx.compose.ui:ui-test-junit4-android:1.6.8")
        debugImplementation("androidx.compose.ui:ui-test-manifest:1.6.8")
    }
}
a
The only decency missing there is the uiTooling one, but all other dependencies did not work even when they were placed where you claim they should
k
This is my whole file. And it works for Android
Copy code
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig

plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidApplication)
    alias(libs.plugins.jetbrainsCompose)
    alias(libs.plugins.compose.compiler)
    alias(libs.plugins.kotlinPluginSerialization)
}

kotlin {
    @OptIn(ExperimentalWasmDsl::class)
    wasmJs {
        moduleName = "composeApp"
        browser {
            val projectDirPath = project.projectDir.path
            commonWebpackConfig {
                outputFileName = "composeApp.js"
                devServer = (devServer ?: KotlinWebpackConfig.DevServer()).apply {
                    static = (static ?: mutableListOf()).apply {
                        // Serve sources to debug inside browser
                        add(projectDirPath)
                    }
                }
            }
        }
        binaries.executable()
    }
    
    androidTarget {
        @OptIn(ExperimentalKotlinGradlePluginApi::class)
        compilerOptions {
            jvmTarget.set(JvmTarget.JVM_11)
        }
        @OptIn(ExperimentalKotlinGradlePluginApi::class)
        instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree.test)
    }

    jvm("desktop")

    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }
    }
    
    sourceSets {
        val desktopMain by getting

        androidMain.dependencies {
            implementation(compose.preview)
            implementation(libs.androidx.activity.compose)
        }
        commonMain.dependencies {
            implementation(compose.runtime)
            implementation(compose.foundation)
            implementation(compose.material)
            implementation(compose.ui)
            implementation(compose.components.resources)
            implementation(compose.components.uiToolingPreview)
            implementation(libs.androidx.lifecycle.viewmodel)
            implementation(libs.androidx.lifecycle.runtime.compose)
            implementation(projects.shared)

            api(libs.precompose)
            api(libs.precompose.viewmodel)
            implementation(libs.precompose.navigation.typesafe)

            implementation(libs.kotlinx.serialization.core)
        }

        commonTest.dependencies {
            implementation(kotlin("test"))

            @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
            implementation(compose.uiTest)
        }

        desktopMain.dependencies {
            implementation(compose.desktop.currentOs)
        }
    }
}

android {
    namespace = "com.bngdev.undercover"
    compileSdk = libs.versions.android.compileSdk.get().toInt()

    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    sourceSets["main"].res.srcDirs("src/androidMain/res")
    sourceSets["main"].resources.srcDirs("src/commonMain/resources")

    defaultConfig {
        applicationId = "com.bngdev.undercover"
        minSdk = 21
        targetSdk = libs.versions.android.targetSdk.get().toInt()
        versionCode = 1
        versionName = "1.0"
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    buildFeatures {
        compose = true
    }
    dependencies {
        debugImplementation(compose.uiTooling)
        androidTestImplementation("androidx.compose.ui:ui-test-junit4-android:1.6.8")
        debugImplementation("androidx.compose.ui:ui-test-manifest:1.6.8")
    }
}

tasks.named<Task>("iosSimulatorArm64Test") {
    dependsOn(tasks.clean)
}
it also works for iOS but it looks that currently, compose is not using iOS simulator for executing tests
a
thank you so much, Let me disect it and revert back to you
still getting the same issue 😔 . Do I have need to write any special annotation in my tests?? I am using kotlin.test. annotations. Perhaps that might be the issue??
Somehow I have managed to bring it to this new error
Copy code
java.lang.NoClassDefFoundError: androidx.test.espresso.Espresso
Looks like the tests are being picked up now, but they are now all failing with that error above
k
My test is exact copy of the one from documentation. Maybe issue is related to version of the libs/plugins, I h ave following versions in my lib.versions.tml
Copy code
[versions]
agp = "8.2.2"
android-compileSdk = "34"
android-minSdk = "21"
android-targetSdk = "34"
androidx-activityCompose = "1.9.1"
androidx-appcompat = "1.7.0"
androidx-constraintlayout = "2.1.4"
androidx-core-ktx = "1.13.1"
androidx-espresso-core = "3.6.1"
androidx-lifecycle = "2.8.0"
androidx-material = "1.12.0"
androidx-test-junit = "1.2.1"
compose-plugin = "1.6.11"
junit = "4.13.2"
kotlin = "2.0.20"
kotlinxSerializationCore = "1.6.2"
ktor = "2.3.12"
logback = "1.5.7"
napier = "2.7.1"
navigationTypesafe = "0.3.1L"
precompose = "1.6.2"
uiTestManifest = "1.7.2"
koin-bom = "4.0.0"
a
Thanks @Kamil Kalisz, I had to configure espresso to run the test, and now, my multiplatform tests do run
👍 1