Reputation: 1012
I'm using the IntelliJ IDEA Multiplatform project, and the jsTest Gradle task does not detect any tests. The jvmTest tests run no problem. When I run the jsTest task with debug output, I can see that the task runs and immediately finishes.
Gradle version 4.10.1. Kotlin version 1.3.0-eap.
How can I rectify the Gradle configuration, or what command can I run, so that the test will actually be detected, and (as written) fail?
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'
}
}
}
}
test-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']);
Upvotes: 4
Views: 1879
Reputation: 19130
Inspired by kotlinx-io's multiplatform build configuration, without really knowing what I am doing, I managed to configure JavaScript tests to run using 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
Upvotes: 2
Reputation: 34
As stated by Kotlin Multiplatform Tutorial
At this point, test tasks for Kotlin/JS are created but do not run tests by default; they should be manually configured to run the tests with a JavaScript test framework.
You can use for example mocha framework to run the tests
Here is my setup to do so:
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'
For some reasons it is important to disable metadata feature from gradle, for node plugin to work properly.
With this set up you will run js tests of jsTest
gradle task, (which is important for example for CI) but they won't appear in the idea window as they do for java tests, and you still wouldn't be able to debug them.
To do so in IntelliJ IDEA you can create custom mocha run/debug configuration (Run | Edit Configurations from the main menu), and configure it similar to the runMocha
gradle task.
Upvotes: 1