runTest is a kotlinx.coroutines testing function that runs coroutine-based tests with virtual time. Unlike runBlocking, it fast-forwards delays instead of waiting for them in real time, keeping tests quick as asynchronous behavior grows. section 18.5 section 18.5.1
A delay that completes immediately
@Test fun testDelay() = runTest { val startTime = System.currentTimeMillis() delay(20.seconds) println(System.currentTimeMillis() - startTime) } The coroutine declares a 20-second delay, but virtual time advances it so the test completes in milliseconds. runTest uses a test dispatcher and scheduler, with a default real-time timeout of 60 seconds; pass a timeout when longer integration tests need it. section 18.5.1
Use runTest with these scheduling rules in mind:
- Expect a single-threaded test dispatcher: child coroutines are concurrent with the test but do not run in parallel by default. section 18.5.1
- Provide suspension points such as delay or yield before asserting work launched by child coroutines; otherwise the children may not have run. section 18.5.1
- Control execution with runCurrent, delay-driven virtual-clock advancement, and advanceUntilIdle when assertions require precise scheduling. section 18.5.1 section 18.6
- Test finite flows by collecting with toList, or combine runTest with Turbine to await emissions, completion, and errors. section 18.5.2
Listing 18.11 Running a test with virtual time
import kotlinx.coroutines.*
import kotlinx.coroutines.test.*
import kotlin.test.*
import kotlin.time.Duration.Companion.seconds
class PlaygroundTest {
@Test
fun testDelay() = runTest {
val startTime = System.currentTimeMillis()
delay(20.seconds)
println(System.currentTimeMillis() - startTime)
// 11
}
}
A compact Kotlin test showing runTest, delay, and virtual-time execution. section 18.5.1
