testing-coroutines-with-runtest

Test JVM coroutines deterministically with kotlinx-coroutines-test virtual time.

303|10|Updated May 15, 2026
One-click install
npx skills add https://github.com/skydoves/android-testing-skills --skill testing-coroutines-with-runtest
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: testing-coroutines-with-runtest
Source: https://github.com/skydoves/android-testing-skills/tree/main/jvm-tests/coroutines/testing-coroutines-with-runtest
Command: npx skills add https://github.com/skydoves/android-testing-skills --skill testing-coroutines-with-runtest

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve?

This Skill helps you reliably test suspend functions and coroutine-driven classes on the JVM without real-time delays, flakiness, or tests hanging due to incorrect coroutine test setup.

Core Features & Use Cases

  • Correct entry point with virtual time: Uses runTest with TestScope and virtual clock control via TestCoroutineScheduler.
  • Dispatcher correctness for stateful code: Explains StandardTestDispatcher vs UnconfinedTestDispatcher, and how Dispatchers.setMain prevents missing-main-dispatcher crashes in viewModelScope tests.
  • Flow-collector safety: Covers the common hang scenario when collecting hot flows directly in TestScope, steering you to backgroundScope or the sibling Turbine skill.
  • KMP correctness note: Describes the TestResult contract and why single-expression @Test fun foo() = runTest { ... } matters for Kotlin/JS and wasm targets.

Real-world example: testing a ViewModel that emits Loading -> Success from a coroutine where you need to advance virtual time (advanceUntilIdle or advanceTimeBy) to deterministically assert intermediate states.

Quick Start

Use the testing-coroutines-with-runtest skill when you need to write a JVM runTest for a viewModelScope-backed suspend flow that currently hangs or is timing out in CI.

Frequently Asked Questions about testing-coroutines-with-runtest

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
Why does my Kotlin coroutine test hang when collecting a hot Flow in runTest?

Kotlin coroutine tests hang because collecting hot flows directly in TestScope never completes. Use backgroundScope or a library like Turbine to safely collect emissions without blocking virtual time.

How do I test a ViewModel that emits Loading and Success states using runTest?

Test ViewModel state emissions by replacing real time with virtual time using TestCoroutineScheduler. Call advanceUntilIdle or advanceTimeBy inside runTest to deterministically assert intermediate Loading and Success states.

Do I need to set Dispatchers.setMain for viewModelScope JVM unit testing?

Yes, you need Dispatchers.setMain configured via a MainDispatcherRule for viewModelScope JVM unit testing. Without it, tests crash with a missing main dispatcher error because viewModelScope defaults to Dispatchers.Main.

What is the difference between StandardTestDispatcher and UnconfinedTestDispatcher in kotlinx-coroutines-test?

StandardTestDispatcher queues coroutines without executing them until advanced, whereas UnconfinedTestDispatcher executes eagerly like real code. Choose StandardTestDispatcher for precise virtual time control and UnconfinedTestDispatcher for simpler sequential execution.

Can I use single-expression runTest functions for Kotlin Multiplatform JVM and wasm tests?

Yes, use single-expression @Test fun foo() = runTest { ... } for Kotlin Multiplatform tests. This format fulfills the TestResult contract required by Kotlin/JS and wasm targets to properly return asynchronous test results.