I'm writing coroutine-based multiplatform libraries, and I would love to use these nice testing tools for common code.
Is there any plan to make this library multiplatform? (even with a subset of the features?)
Is there an existing YouTrack issue for this that I could upvote and follow?
I tried copy-pasting the non-internal part of kotlinx-coroutines-test into my common test code.
Apart from a couple JVM-specific annotations, and printStackTrace(), it looks like most of it is in fact pure Kotlin code, and it runs fine in my common tests.
How much work would it represent to publish this lib as multiplatform? (maybe I'm missing something, like a dependency on some other task)
It would really help to have it in multiplatform. Mainly for JS.
Same issue.
For anyone finding this issue and wanting a workaround for testing coroutines in common code, here's what I'm using right now (someone posted the JS workaround with promises in the forums somewhere, I'm not the author of that):
// Common code:
expect fun runBlockingTest(block: suspend () -> Unit)
expect val testCoroutineContext: CoroutineContext
// JVM code:
actual val testCoroutineContext: CoroutineContext =
Executors.newSingleThreadExecutor().asCoroutineDispatcher()
actual fun runBlockingTest(block: suspend () -> Unit) =
runBlocking(testCoroutineContext) { block() }
// JS code:
val testScope = MainScope()
actual val testCoroutineContext: CoroutineContext = testScope.coroutineContext
actual fun runBlockingTest(block: suspend () -> Unit): dynamic = testScope.promise { block() }
// Example common test:
@Test
fun testMyCoroutines() = runBlockingTest {
// ...
}
Of course, this doesn't have all the features of kotlinx-coroutines-test, but it's working well enough for me.
To add on to @nunocastromartins answer, if you want to use the coroutine scope in your runBlockingTest suspend block it can be modified to
expect fun runBlockingTest(block: suspend CoroutineScope.()-> Unit)
expect val testCoroutineContext: CoroutineContext
// JVM code:
actual val testCoroutineContext: CoroutineContext =
Executors.newSingleThreadExecutor().asCoroutineDispatcher()
actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit) =
runBlocking(testCoroutineContext) { this.block() }
// JS code:
val testScope = MainScope()
actual val testCoroutineContext: CoroutineContext = testScope.coroutineContext
actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit): dynamic = testScope.promise { this.block() }
//iOS code:
actual val testCoroutineContext: CoroutineContext =
newSingleThreadContext("testRunner")
actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit) =
runBlocking(testCoroutineContext) { this.block() }
Now you can easily use things like async{} or launch{} inside of the runBlockingTest code
Burned a day trying to figure out why adding kotlinx-coroutines-test to commonTest made my whole project fall apart -- I didn't realize the artifact is JVM only!
The top-level README indicates that the project supports multiplatform, so it seems like a reasonable assumption that everything supports multiplatform unless marked otherwise
Are there any plans to bring kotlin-coroutines-test to the multiplatform world?
In the meantime, should the docs (both the top-level README, and the README inside kotlinx-coroutines-test) clearly say that -test is JVM-only?
Or further: should we rename the artifact to something like kotlinx-coroutines-test-jvm?
@qwwdfsad are there any plans for this in the foreseeable future? I have trouble estimating the amount of work required to make this possible. Do you have any insight about this?
Most helpful comment
To add on to @nunocastromartins answer, if you want to use the coroutine scope in your runBlockingTest suspend block it can be modified to
Now you can easily use things like
async{}orlaunch{}inside of the runBlockingTest code