Testing Coroutines & Flow Interview Questions

TESTING › Unit

When would writing a coroutine test actually still require a real dispatcher or real wall-clock time, rather than relying on runTest's virtual time? Give a concrete example.

What a strong answer covers: Virtual time only fast-forwards coroutines scheduled through the shared TestCoroutineScheduler; work that crosses into a genuinely separate scheduler, such as a third-party SDK's own executor, a real network client's IO threads, or an Android Handler you don't control, still runs on wall-clock time and won't be advanced by advanceUntilIdle. The common misconception is assuming runTest speeds up all async work in the test; in practice you either wrap that boundary so it goes through injected coroutines sharing the test scheduler, or accept a real, short timeout for that specific interaction.

You have a Flow built with debounce(300) feeding a search UI. How do you test that debounce behavior deterministically without waiting 300 real milliseconds?

What a strong answer covers: Drive the test with runTest's virtual time and advance the TestCoroutineScheduler explicitly, for example advanceTimeBy(299) to assert nothing has emitted yet and then past 300 to assert exactly one emission, collecting with something like Turbine so you can assert ordering precisely. The trap is reaching for a shorter debounce value or a real delay just to make the test fast; virtual time makes that unnecessary and keeps the test both fast and faithful to production timing.

Walk me through how you'd test a suspend function that retries on failure with exponential backoff, three attempts with delay(1000), delay(2000), delay(4000) between them.

What a strong answer covers: Use a fake or mock that fails the first N calls and then succeeds, run it inside runTest, and use advanceUntilIdle (or step through with advanceTimeBy at each expected boundary if you also need to assert the specific intervals) so all the backoff waits collapse to virtual time instead of real seconds, then assert the call count and, if relevant, that no attempt happened before its threshold. Testing this with real delays would make the suite slow and risks flakiness under CI load if the timing is tight; virtual time gives you exact, deterministic control over when each retry fires.

Back to Testing Coroutines & Flow