Hey guys, I'm trying to run the example iOS websoc...
# kotlin-native
j
Hey guys, I'm trying to run the example iOS websocket code from Kotlin docs' example in my
iosTest
(unit tests), but everything is just stuck. I saw this comment in a very old thread, and I'm thinking maybe it's the same "queue is not run" problem. Is there anyway for me to run this queue within an iOS unit test? I'm writing a multiplatform library so I don't have an iOS app project. It looks like I don't have access to
NSApplication
there.
I dug some more and found
NSRunLoop.mainRunLoop.run()
which seems to execute that main loop, but I don't see how I can use it inside unit tests. The test seems to run in the main loop itself, so how can I yield the main thread to coroutines, but still have the test framework wait for the test to finish?
t
the trick is to run the tests off a background thread instead of the main thread. you can do this by making a custom test entry point like this: https://github.com/splendo/kaluga/blob/develop/test-utils/src/iosMain/kotlin/mainBackground.kt and then configure in gradle that it’s used like this: https://github.com/splendo/kaluga/tree/develop/test-utils#testing-from-a-background-thread-to-let-dispatchersmain-function-properly
this is actually also an issue in regular iOS tests (posting to the dispatcher does not work), iOS developers often use
defer
in this situation as this will run after the test (quite ugly in my opinion)
j
Thanks, that's interesting! I had sort of come up with a solution already that didn't imply changing the entry point for tests. It basically fires a coroutine for the test and runs the main loop manually a little bit a at a time, but yields from time to time so the test coroutine can progress. If you really run tests in a background thread, you end up with shared state issues right? I guess my tests do need to run in the main thread for this reason, so I still need some kind of mechanism to distribute the main thread work between test code and main loop run
t
yes, you do run into the memory model.. though you can also work around that, if you launch a coroutine on the main thread, and just do everything from there, then all memory is in the same thread.
the test-utils module in kaluga I linked (I’m co-author of that library) has helper classes for that, as described in the readme I linked
j
if you launch a coroutine on the main thread, and just do everything from there, then all memory is in the same thread
Yes, that's actually what I do to avoid problems, but if the main thread is busy running your coroutine it cannot run the main loop. So I cannot use things that block indefinitely like
CFRunLoopRun()
(I don't see how that works in your library). Instead I have to progress the main loop little by little (e.g. using
NSRunLoop.mainRunLoop.runUntilDate(date)
) like it's done here: https://github.com/ktorio/ktor/issues/678#issuecomment-433756753
I will look into your test-utils library in any case, and probably give it a try too 🙂
t
ok, let me know if you have questions
🙏 1
👍 1