[英]Kotlin-multiplatform: How to execute iOS unit tests
I'm working on a Kotlin-multiplatform library for Android and iOS.我正在为 Android 和 iOS 开发 Kotlin 多平台库。 I want to write some platform-specific unit test.
我想编写一些特定于平台的单元测试。 The tests run as expected for the shared code and Android but not for iOS.
共享代码和 Android 的测试按预期运行,但不适用于 iOS。
Below the build.gradle
file of the shared code module.在共享代码模块的
build.gradle
文件下面。
apply plugin: "kotlin-multiplatform"
kotlin {
targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
? presets.iosArm64 : presets.iosX64
fromPreset(iOSTarget, 'iOS') {
compilations.main.outputKinds('FRAMEWORK')
}
fromPreset(presets.jvm, 'android')
}
sourceSets {
commonMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common"
}
commonTest.dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test'
implementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
androidMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
}
androidTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test'
implementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
}
iOSMain.dependencies {
}
iOSTest.dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test'
implementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
}
}
// workaround for https://youtrack.jetbrains.com/issue/KT-27170
configurations {
compileClasspath
}
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
inputs.property "mode", mode
dependsOn kotlin.targets.iOS.compilations.main.linkTaskName("FRAMEWORK", mode)
from { kotlin.targets.iOS.compilations.main.getBinary("FRAMEWORK", mode).parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXCode
and the structure of the SharedCode
module is: SharedCode
模块的结构为:
└── src
├── commonMain
│ └── kotlin
├── commonTest
│ └── kotlin
├── androidMain
│ └── kotlin
├── androidTest
│ └── kotlin
├── iOSMain
│ └── kotlin
└── iOSTest
└── kotlin
The tests added in the androidTest
and commonTest
folders do run as expected but the ones added in the iOSTest
do not run.在
androidTest
和commonTest
文件夹中添加的测试确实按预期运行,但在iOSTest
添加的iOSTest
没有运行。
However, if I replace the the line fromPreset(iOSTarget, 'iOS') { compilations.main.outputKinds('FRAMEWORK') }
for fromPreset(presets.macosX64, 'macos')
and update the directory names accordly, the tests in the macosTest
folder do run as expected.但是,如果我将
fromPreset(iOSTarget, 'iOS') { compilations.main.outputKinds('FRAMEWORK') }
fromPreset(presets.macosX64, 'macos')
为fromPreset(presets.macosX64, 'macos')
并相应地更新目录名称,则测试macosTest
文件夹确实按预期运行。
Why it is not possible to run iOS test when building iOS frameworks?为什么在构建 iOS 框架时无法运行 iOS 测试? Any idea about what I'm doing wrong or how I can make this works?
知道我做错了什么或如何使其有效吗? :)
:)
Currently the kotlin-multiplatform
plugin supports only running tests for host platforms (eg macOS or Windows).目前
kotlin-multiplatform
插件仅支持对主机平台(例如 macOS 或 Windows)运行测试。 But you can manually add a task for executing iOS tests on a simualtor:但是你可以手动添加一个在模拟器上执行 iOS 测试的任务:
task iosTest {
def device = project.findProperty("iosDevice")?.toString() ?: "iPhone 8"
dependsOn 'linkTestDebugExecutableIos'
group = JavaBasePlugin.VERIFICATION_GROUP
description = "Runs tests for target 'ios' on an iOS simulator"
doLast {
def binary = kotlin.targets.ios.binaries.getExecutable('test', 'DEBUG').outputFile
exec {
commandLine 'xcrun', 'simctl', 'spawn', device, binary.absolutePath
}
}
}
As I ran into some issues, I'll post my solution here.当我遇到一些问题时,我会在这里发布我的解决方案。
With Kotlin 1.3.50
and XCode 11
I had to change my command line arguments:使用 Kotlin
1.3.50
和 XCode 11
我不得不更改我的命令行参数:
val iosTest: Task by tasks.creating {
val device = project.findProperty("iosDevice")?.toString() ?: "iPhone 8"
val testExecutable = kotlin.targets.getByName<KotlinNativeTarget>("iosX64").binaries.getTest("DEBUG")
dependsOn(testExecutable.linkTaskName)
group = JavaBasePlugin.VERIFICATION_GROUP
description = "Runs tests for target 'ios' on an iOS simulator"
doLast {
exec {
println(testExecutable.outputFile.absolutePath)
commandLine( "xcrun", "simctl", "spawn", "--standalone", device, testExecutable.outputFile.absolutePath)
}
}
}
tasks.getByName("allTests").dependsOn(iosTest)
The answer from @IlyaMatveev works perfect for me. @IlyaMatveev 的答案对我来说很完美。 But I had to updates two lines using Kotlin Version 1.3.41:
但我不得不使用 Kotlin 1.3.41 版更新两行:
dependsOn 'linkTestDebugExecutableIos'
is now dependsOn 'linkDebugTestIos'
dependsOn 'linkTestDebugExecutableIos'
现在是dependsOn 'linkDebugTestIos'
def binary = kotlin.targets.ios.binaries.getExecutable('test', 'DEBUG').outputFile
is now def binary = kotlin.targets.ios.binaries.getTest("DEBUG").outputFile
def binary = kotlin.targets.ios.binaries.getExecutable('test', 'DEBUG').outputFile
现在是def binary = kotlin.targets.ios.binaries.getTest("DEBUG").outputFile
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.