Virtual time makes coroutine tests fast by replacing real waiting with a test-controlled clock. Under runTest, delays are automatically fast-forwarded, so behavior that includes long debounce or timeout delays can be checked in milliseconds rather than making the suite wait in real time. section 18.5 section 18.5.1
Fast-forward a delayed coroutine
Use runTest as the test body. A delay of 20 seconds is scheduled on its test dispatcher rather than slept in real time, so the assertion or subsequent code can run almost immediately. The default runTest timeout remains 60 real-time seconds; pass a timeout when an integration-style test genuinely needs longer. section 18.5.1
Virtual time controls scheduled coroutine work, not parallel execution. runTest uses a single-threaded dispatcher by default: launched children run concurrently but need a suspension point before they can make progress alongside test code. Calling an assertion immediately after launch can therefore observe unchanged state. Use delay, yield, or another suspending call when the test must let shared-dispatcher work run. section 18.5.1
Advance and inspect scheduled work deliberately when a test needs intermediate states:
- Use delay inside runTest to move the virtual clock forward by a chosen duration; currentTime reports the resulting virtual time. section 18.5.1
- Use runCurrent() to execute work scheduled at the current virtual time without advancing the clock. section 18.6
- Use advanceUntilIdle() to run scheduled coroutines until no work remains, including later delayed work. section 18.5.1
Listing 18.12 Forwarding the virtual clock with delay
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun testDelay() = runTest {
var x = 0
launch {
delay(500.milliseconds)
x++
}
launch {
delay(1.second)
x++
}
println(currentTime) // 0
delay(600.milliseconds)
assertEquals(1, x)
println(currentTime) // 600
delay(500.milliseconds)
assertEquals(2, x)
println(currentTime) // 1100
}
This timeline-style test shows two delayed coroutines becoming observable at 600 ms and 1100 ms of virtual time, without waiting for either interval in real time. section 18.5.1
Treat virtual time as a way to test time-dependent coroutine behavior deterministically and quickly. It is especially useful when repeated delays would otherwise make a growing test suite cumbersome to run, reducing the incentive to run tests frequently. section 18.5 section 18.6
