Error Running Unit Tests for Kotlin Multiplatform Project

2.3k views Asked by At

I have created a Kotlin multiplatform project using Intelli-j IDE (community edition) following a tutorial from this site:

https://medium.com/@cafonsomota/set-up-your-first-kotlin-multiplatform-project-for-android-and-ios-april-2020-258e2b1d9ef4

What I have not followed is the xCode part of the tutorial since, at this point although I want this project to be multiplatform, my primary interest is for Android.

When I am running the common sample tests, I see the error: e: org.jetbrains.kotlin.konan.MissingXcodeException: An error occurred during an xcrun execution. Make sure that Xcode and its command line tools are properly installed.

I can also see that the for the associated configuration, tasks details the following: cleanIosTest iosTest

That is why I am receiving the error.

What I can't figure out is how to change Sample Test to not run that configuration. I have tried to remove those tasks, Apply and Save but they keep reappearing when I run them. I can't see anything in the build.gradle files that indicates anything iOS specific for testing.

build.gradle.app

    plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.3.72'
}
repositories {
    google()
    jcenter()
    mavenCentral()
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId 'org.jetbrains.kotlin.mpp_app_android'
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName '1.0'
        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
    }
    buildTypes {
        release {
            minifyEnabled false
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
}

kotlin {
    android("android")
    // This is for iPhone emulator
    // Switch here to iosArm64 (or iosArm32) to build library for iPhone device
    iosX64("ios") {
        binaries {
            framework()
        }
    }
    sourceSets {
        commonMain {
            dependencies {
                implementation kotlin('stdlib-common')
            }
        }
        commonTest {
            dependencies {
                implementation kotlin('test-common')
                implementation kotlin('test-annotations-common')
            }
        }
        androidMain {
            dependencies {
                implementation kotlin('stdlib')
            }
        }
        androidTest {
            dependencies {
                implementation kotlin('test')
                implementation kotlin('test-junit')
            }
        }
        iosMain {
        }
        iosTest {
        }
    }
}

// This task attaches native framework built from ios module to Xcode project
// (see iosApp directory). Don't run this task directly,
// Xcode runs this task itself during its build process.
// Before opening the project from iosApp directory in Xcode,
// make sure all Gradle infrastructure exists (gradle.wrapper, gradlew).
task copyFramework {
    def buildType = project.findProperty('kotlin.build.type') ?: 'DEBUG'
    def target = project.findProperty('kotlin.target') ?: 'ios'
    dependsOn kotlin.targets."$target".binaries.getFramework(buildType).linkTask

    doLast {
        def srcFile = kotlin.targets."$target".binaries.getFramework(buildType).outputFile
        def targetDir = getProperty('configuration.build.dir')
        copy {
            from srcFile.parent
            into targetDir
            include 'app.framework/**'
            include 'app.framework.dSYM'
        }
    }
}

The Sample tests look like this:

package sample

import kotlin.test.Test
import kotlin.test.assertTrue

class SampleTests {
    @Test
    fun testMe() {
        assertTrue(Sample().checkMe() > 0)
    }

    @Test
    fun testProxy() {
        assertTrue(Proxy().proxyHello().isNotEmpty())
    }
}

The configuration looks like this:

Configuration

Does anyone know how I can resolve this without needing to download xCode? I am happy to share any other information but am not truthfully sure what I should be sharing for this.

Incidentally, I did create another configuration without that line but, when I press the green PLAY button on the first test, it always defaults to the Sample Test configuration with the iOS tasks in.

1

There are 1 answers

4
Artyom Degtyarev On

This problem is caused by the bug, already described in the Kotlin issue tracker, see here. If you want to run Android-only tests, you should go with Gradle tasks named test<Debug | Release>UnitTest instead of the allTests, which includes the only iOS in your case.