# Coroutine Testing - Picking the right Dispatcher

DevFeed: [Coroutine Testing - Picking the right Dispatcher](<https://devfeed.tech/articles/coroutine-testing-picking-the-right-dispatcher-25237.md>)

Original publisher: [Read original article](<https://kau.sh/blog/coroutine-testing-dispatchers/>)

Author: Kaushik Gopal

Published: 2024-08-25T07:00:45Z

Content type: tutorial

Language: en

Sources: [Kaushik Gopal's Site](<https://devfeed.tech/sources/kaushik-gopal-s-site.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [test](<https://devfeed.tech/topics/test.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [coroutine-testing](<https://devfeed.tech/tags/coroutine-testing.md>), [dispatcher](<https://devfeed.tech/tags/dispatcher.md>), [flaky](<https://devfeed.tech/tags/flaky.md>), [scope](<https://devfeed.tech/tags/scope.md>), [strategy](<https://devfeed.tech/tags/strategy.md>), [testing](<https://devfeed.tech/tags/testing.md>)

## AI overview

This tutorial explains how CoroutineContext, CoroutineScope, and Dispatchers affect coroutine tests. It recommends explicitly injecting a CoroutineScope and replacing it with TestScope to control dispatchers, reduce flakiness, and make tests run faster.

## Source excerpt

series This is part of a series of posts on Coroutine Testing: Picking the right Dispatcher <- Never ending tests & backgroundscope Controlling time Helpful @Junit TestRule extension (coming soon) Full USF example for Android (coming soon) Most of the problems and flakiness around coroutine testing stem from running them on different Dispatchers. This is because the choice of Dispatcher can significantly impact the behavior of coroutines. This was also the most confusing1 part for me starting out -- understanding the implications of using a Scope, Context or Dispatcher. I recommend Roman's article if you want to brush up on the fundamentals. But in a nutshell: think of CoroutineContext as a collection of elements that define the coroutine. It contains a Dispatcher, Job & a CoroutineName. When you launch a coroutine, it inherits the parent's CoroutineContext (and Dispatcher), unless you specify it explicitly. A CoroutineScope on the other hand is just a way to manage and cancel (multiple) coroutines. It also defines a context and lifecycle for the coroutines launched within it (the context could be linked to yet another Dispatcher). Any coroutine when launched, runs within a CoroutineScope. Let's take an example: Notice how the current Dispatcher of the coroutine shifts from StandardTestDispatcher -> UnconfinedTestDispatcher -> Dispatcher.IO in the span of three innocuous lines based on the coroutine builder (runTest) or scope used (TestScope, turbineScope from the 3rd party library, App scope). In my initial post I pointed out this flaky test: flaky test code on github The fix for this is as simple as explicitly injecting a TestScope and making sure the same scope is used throughout. fixed test code on github Explicitly injecting the CoroutineScope and substituting it with the TestScope works really well and is my preferred strategy. This approach allows for more control over the Dispatcher used in tests . For reasons you'll see later, these tests also run instantly (72