testing-coroutines-with-runtest
Installation
SKILL.md
Testing Coroutines With runTest — Virtual Time Without Wall Clock
runTest is the only correct entry point for testing suspend functions and viewModelScope-backed code on the JVM. This skill nails down the TestScope contract, the two TestDispatcher flavors, the shared TestCoroutineScheduler virtual clock, and the MainDispatcherRule plumbing that keeps Dispatchers.setMain from leaking between tests. Flow-specific assertions live in ../testing-flows-with-turbine/SKILL.md.
When to use this skill
- The class under test exposes a
suspend funor launches intoviewModelScope/lifecycleScope. - The developer reaches for
runBlocking { … }and the test hangs, or a 10-minutedelaymakes the test slow. - A ViewModel emits
Loading -> Successfrom a coroutine and the test needs to assert each intermediate state. - The build emits the deprecation
runBlockingTest is deprecated. Use runTestorrunTest(... dispatchTimeoutMs = ...)errors. - The test fails with
IllegalStateException: Module with the Main dispatcher is missingbecauseviewModelScoperouted work throughDispatchers.Main. - The developer needs to advance virtual time (
advanceTimeBy(5.seconds),advanceUntilIdle()) to trigger a timeout / retry / debounce.
When NOT to use this skill
- The test asserts
Flowemissions across time. Use../testing-flows-with-turbine/SKILL.md(Turbine handles cancellation, hot vs cold,awaitItem/awaitComplete). - The test exercises Compose's
MainTestClockrather thankotlinx.coroutines.test. Use../../../compose/synchronization/controlling-the-test-clock/SKILL.md. - The test runs on an emulator/device through AndroidJUnit4. JUnit4 setup itself is
../../runner/configuring-junit4-on-android/SKILL.md.