如何让我的 JS 测试出现在 Kotlin 多平台项目中



我正在使用IntelliJ IDEA多平台项目,jsTest Gradle任务没有检测到任何测试。 jvmTest 测试运行没有问题。 当我使用调试输出运行 jsTest 任务时,我可以看到任务运行并立即完成。

Gradle 版本 4.10.1。 Kotlin 版本 1.3.0-eap。

如何纠正 Gradle 配置,或者我可以运行什么命令,以便实际检测到测试并(如所写的那样(失败?

build.gradle:

plugins {
id 'kotlin-multiplatform' version '1.3.0-rc-131'
}
repositories {
maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' }
mavenCentral()
}
kotlin {
targets {
fromPreset(presets.jvm, 'jvm')
fromPreset(presets.js, 'js')
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
commonTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test-common'
implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
}
}
jvmTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test'
implementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
}
jsMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-js'
}
}
jsTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test-js'
}
}
}
}

测试project_test.js:

if (typeof kotlin === 'undefined') {
throw new Error("Error loading module 'test-project_test'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'test-project_test'.");
}
if (typeof this['test-project'] === 'undefined') {
throw new Error("Error loading module 'test-project_test'. Its dependency 'test-project' was not found. Please, check whether 'test-project' is loaded prior to 'test-project_test'.");
}
if (typeof this['kotlin-test'] === 'undefined') {
throw new Error("Error loading module 'test-project_test'. Its dependency 'kotlin-test' was not found. Please, check whether 'kotlin-test' is loaded prior to 'test-project_test'.");
}
this['test-project_test'] = function (_, Kotlin, $module$test_project, $module$kotlin_test) {
'use strict';
var Sample = $module$test_project.sample.Sample;
var assertTrue = $module$kotlin_test.kotlin.test.assertTrue_ifx8ge$;
var Kind_CLASS = Kotlin.Kind.CLASS;
var hello = $module$test_project.sample.hello;
var contains = Kotlin.kotlin.text.contains_li3zpu$;
var test = $module$kotlin_test.kotlin.test.test;
var suite = $module$kotlin_test.kotlin.test.suite;
function SampleTests() {
}
SampleTests.prototype.testMe = function () {
assertTrue((new Sample()).checkMe() > 0);
};
SampleTests.$metadata$ = {
kind: Kind_CLASS,
simpleName: 'SampleTests',
interfaces: []
};
function SampleTestsJS() {
}
SampleTestsJS.prototype.testHello = function () {
assertTrue(contains(hello(), 'JSSDF'));
};
SampleTestsJS.$metadata$ = {
kind: Kind_CLASS,
simpleName: 'SampleTestsJS',
interfaces: []
};
var package$sample = _.sample || (_.sample = {});
package$sample.SampleTests = SampleTests;
package$sample.SampleTestsJS = SampleTestsJS;
suite('sample', false, function () {
suite('SampleTests', false, function () {
test('testMe', false, function () {
return (new SampleTests()).testMe();
});
});
suite('SampleTestsJS', false, function () {
test('testHello', false, function () {
return (new SampleTestsJS()).testHello();
});
});
});
Kotlin.defineModule('test-project_test', _);
return _;
}(typeof this['test-project_test'] === 'undefined' ? {} : this['test-project_test'], kotlin, this['test-project'], this['kotlin-test']);

如 Kotlin 多平台教程所述

此时,Kotlin/JS 的测试任务已创建,但默认情况下不运行测试;应手动配置它们以使用 JavaScript 测试框架运行测试。

例如,您可以使用摩卡框架来运行测试

这是我这样做的设置:

build.gradle:

plugins {
id 'kotlin-multiplatform' version '1.3.10' //I'm using the released version of plugin,
//but it seems that they have same API
id 'com.moowork.node' version '1.2.0' //plugin for installing node
//and running node and npm tasks
}
repositories {
mavenCentral()
}
group 'com.example'
version '0.0.1'
apply plugin: 'maven-publish'
final kotlinRuntimeVersion = '1.3.10'
final nodeVersion = '11.2.0'
final nodeWorkingDir = project.buildDir
final nodeModules = "$nodeWorkingDir/node_modules"
final mochaVersion = '5.2.0'
final pathSeparator = System.properties["path.separator"]
kotlin {
targets {
fromPreset(presets.jvm, 'jvm')
fromPreset(presets.js, 'js') {
[compileKotlinJs, compileTestKotlinJs].each { configuration ->
configuration.kotlinOptions {
moduleKind = 'umd'
}
}
}
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
commonTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test-common'
implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
}
}
jvmTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test'
implementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
}
jsMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-js'
}
}
jsTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test-js'
}
}
}
}
//Workaround to copy kotlin libraries so they are visible during testing
def jsLibDir = "$compileKotlinJs.destinationDir/lib"
def jsTestLibDir = "$compileTestKotlinJs.destinationDir/lib"
configurations {
jsLibs
jsTestLibs
}
dependencies {
jsLibs "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinRuntimeVersion"
jsTestLibs "org.jetbrains.kotlin:kotlin-test-js:$kotlinRuntimeVersion"
}
task copyJsDependencies(type: Copy, dependsOn: compileKotlinJs) {
configurations.jsLibs.each {
from zipTree(it.absolutePath).matching { include '*.js'}
}
into jsLibDir
}
jsMainClasses.dependsOn copyJsDependencies
task copyJsTestDependencies(type: Copy) {
configurations.jsTestLibs.each {
from zipTree(it.absolutePath).matching { include '*.js'}
}
into jsTestLibDir
}
jsTestClasses.dependsOn copyJsTestDependencies
//Use mocha to run js tests
node {
version = nodeVersion
download = true
workDir = file("$project.buildDir/nodejs")
nodeModulesDir = file(nodeWorkingDir)
}
task installMocha(type: NpmTask, group: 'npm') {
outputs.dir "$nodeModules/mocha"
args = ['install', "mocha@$mochaVersion"]
}
task runMocha(type: NodeTask, dependsOn: [installMocha, jsMainClasses, jsTestClasses], group: 'npm') {
environment = [ "NODE_PATH": "$jsLibDir$pathSeparator$jsTestLibDir$pathSeparator$compileKotlinJs.destinationDir" ]
script = file("$nodeWorkingDir/node_modules/mocha/bin/mocha")
args = [compileTestKotlinJs.outputFile]
}
jsTest.dependsOn runMocha

settings.gradle:

pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == "kotlin-multiplatform") {
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
}
}
}
}
rootProject.name = 'test'

出于某些原因,从 gradle 禁用元数据功能对于节点插件正常工作非常重要。

完成此设置后,您将运行jsTestgradle 任务的 js 测试(例如,这对于 CI 很重要(,但它们不会像 java 测试那样出现在想法窗口中,并且您仍然无法调试它们。

要在IntelliJ IDEA中执行此操作,您可以创建自定义摩卡运行/调试配置(运行|从主菜单中编辑配置(,并对其进行类似于runMochagradle 任务的配置。

受到 kotlinx-io 的多平台构建配置的启发,在不知道我在做什么的情况下,我设法将 JavaScript 测试配置为使用 Mocha 运行。

compileKotlinJs.configure {
kotlinOptions {
metaInfo = true
sourceMap = true
moduleKind = 'umd'
main = "noCall"
sourceMapEmbedSources = 'always'
}
}
compileTestKotlinJs.configure {
kotlinOptions {
metaInfo = true
sourceMap = true
moduleKind = 'umd'
main = "call"
sourceMapEmbedSources = 'always'
}
}
task copyJsDependencies(type: Copy, dependsOn: compileTestKotlinJs) {
from compileKotlinJs.destinationDir
into "${buildDir}/node_modules"
def configuration = configurations.jsTestRuntimeClasspath
from(files {
configuration.collect { File file ->
file.name.endsWith(".jar")
? zipTree(file.absolutePath).matching {
include '*.js'
include '*.js.map' }
: files()
}
}.builtBy(configuration))
}
node {
version = nodeVersion
download = true
}
task installMocha(type: NpmTask) {
args = ['install', 'mocha']
}
task runMocha(type: NodeTask, dependsOn: [installMocha, compileTestKotlinJs, copyJsDependencies]) {
script = file('node_modules/mocha/bin/mocha')
args = [compileTestKotlinJs.outputFile]
}
jsTest.dependsOn runMocha

最新更新