Thread
#multiplatform
    j

    José González Gómez

    1 year ago
    Can you use shared resources for tests in a Kotlin Multiplatform Mobile project? I tried to include some JSON files under
    src/commonTest/resources
    but they don't seem to get copied to the output directory when running Android tests. Putting them under
    src/androidTest/resources
    did the trick for Android tests, but I don't want to have two copies of these files, as they are common for both Android and iOS tests.
    Derek Ellis

    Derek Ellis

    1 year ago
    I wrote this to make use of test resources in common tests: https://gist.github.com/dellisd/a1df42787d42b41cd3ce16f573984674 It reads them from the
    commonTest/resources
    directory, but in a lot of cases that's good enough.
    j

    José González Gómez

    1 year ago
    thanks!
    n

    Nicolas Verinaud

    1 year ago
    Creating symbolic links might also do the trick. 🙂
    j

    José González Gómez

    1 year ago
    🤔 I'm afraid we've got too many Windows machines hanging around for Android development...
    m

    Michal Klimczak

    1 year ago
    Oh, I was just wondering about the same thing yesterday, but I don't have idea how to approach this with iosTest target. https://kotlinlang.slack.com/archives/C3SGXARS6/p1620045905289200?thread_ts=1620045905.289200&cid=C3SGXARS6
    I just had a massive ide issue around using
    androidTest/resources
    . In case anyone has the same: https://kotlinlang.slack.com/archives/C3PQML5NU/p1620201399394700?thread_ts=1620195839.390000&cid=C3PQML5NU
    j

    José González Gómez

    1 year ago
    Ok, I finally managed to do it, although there are some cases that still don't work... I put the shared test resources under
    commonTest/resources
    , and then add the following snippet in the shared project's build.gradle.kts:
    afterEvaluate {
        listOf("debug", "release").forEach { variant ->
            val copyTaskName = "copyResources${variant.capitalize()}UnitTest"
            tasks.register<Copy>(copyTaskName) {
                from("$projectDir/src/commonTest/resources")
                into("$buildDir/tmp/kotlin-classes/${variant}UnitTest/")
            }
            tasks.getByName("test${variant.capitalize()}UnitTest") {
                dependsOn(copyTaskName)
            }
        }
    
        tasks.register<Copy>("copyResourcesIosX64DebugTest") {
            from("$projectDir/src/commonTest/resources")
            into("$buildDir/bin/iosX64/debugTest/")
        }
        tasks.getByName("iosX64Test") {
            dependsOn("copyResourcesIosX64DebugTest")
        }
    }
    and then I have a expect/actual class to load resources:
    expect class TestResource(path: String) {
        val content: String?
    }
    
    actual class TestResource actual constructor(path: String) {
        actual val content: String? = NSString.stringWithContentsOfFile(NSBundle.mainBundle.pathForResource(path, null)!!) as String?
    }
    
    actual class TestResource actual constructor(path: String) {
        actual val content: String? = this::class.java.classLoader?.getResource(path)?.readText()
    }
    Be careful! The
    into
    directories seem to change depending on the Android Studio / Gradle version
    Maybe somebody with more Gradle experience than me can help with this... with this solution the first time I execute
    ./gradlew testDebugUnitTest
    after a
    ./gradlew clean
    the build fails because the files aren't copied to the destination. The second time the files are copied and the build is successful. I thought that maybe the copy task doesn't create the target directory, so I tried to manually create it before executing the tests, but this didn't work
    found the culprit, the Kotlin compilation deletes the destination directory, so the copy task must be run after them:
    // Top of build.gradle.kts
    import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
    
    // Inside the task definition
            tasks.register<Copy>(copyTaskName) {
                ...
                mustRunAfter(tasks.withType<KotlinCompile>())
            }
    g

    goncalossilva

    9 months ago
    Inspired by this discussion (and @Derek Ellis’s gist!), I’ve open-sourced goncalossilva/kotlinx-resources 🙂