コルーチンのテスト
suspend関数をテストします
「コルーチンのテスト」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
コルーチンのテストが特別な理由
コルーチンは非同期に実行され、遅延を使用することがあります。テストには制御された時間と、suspend関数の完了を待つ手段が必要です。
kotlinx-coroutines-testライブラリは、まさにこの機能を提供します。
テストライブラリの追加
コルーチンのテストアーティファクトをテスト用の依存関係に追加します。
dependencies {
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1")
}runTest
runTestがエントリーポイントです。コルーチンのテスト本体を実行し、すべての子コルーチンが完了するまで自動的に待機します。
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
class FetchTest {
@Test
fun fetches() = runTest {
// suspend calls allowed here
}
}仮想時間
runTest内では、仮想時間を使ってdelayの呼び出しをスキップします。10秒の遅延も、実行順序を維持したまま即座に完了します。
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.runTest
// runTest {
// delay(10_000) // returns immediately
// }時間の手動操作
テストスケジューラーを使うと、advanceTimeByで時間を意図的に進めたり、runCurrentで保留中の処理を実行したりできます。
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
// runTest {
// launch { delay(1000); println("done") }
// advanceTimeBy(1000)
// runCurrent()
// }テスト用ディスパッチャー
StandardTestDispatcherは時間を進めるまでコルーチンをキューに入れます。UnconfinedTestDispatcherはコルーチンを即座に実行します。必要な制御の度合いに応じて選択してください。
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.UnconfinedTestDispatcher
val standard = StandardTestDispatcher()
val unconfined = UnconfinedTestDispatcher()ディスパッチャーの注入
本番コードでは、Dispatchers.IOを直接指定するのではなく、ディスパッチャーを受け取るようにします。そうすれば、テストではテスト用ディスパッチャーを注入できます。
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class Service(private val io: CoroutineDispatcher = Dispatchers.IO) {
suspend fun load(): String = withContext(io) { "data" }
}Dispatchers.Mainの置き換え
Android形式のコードでは、Dispatchers.setMain(testDispatcher)を使ってMainディスパッチャーを置き換え、後でリセットします。
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.test.setMain
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.StandardTestDispatcher
// Dispatchers.setMain(StandardTestDispatcher())
// ... test ...
// Dispatchers.resetMain()Suspend関数のテスト
runTest内では、suspend関数を直接呼び出してアサーションできます。
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
suspend fun compute(): Int { delay(1000); return 42 }
// @Test fun computes() = runTest {
// assertEquals(42, compute())
// }Flowのテスト
Flowを収集し、発行された値をアサーションします。Turbineライブラリを使うと、Flowのテストを特にすっきりと記述できます。
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
// @Test fun emits() = runTest {
// val values = flowOf(1, 2, 3).toList()
// assertEquals(listOf(1, 2, 3), values)
// }実行可能なコルーチンスニペット
テストの外では、runBlockingがsuspendコードと通常のmainの橋渡しをします。これは、テスト対象のsuspend関数を示す例です。
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.delay
suspend fun compute(): Int { delay(100); return 42 }
fun main() = runBlocking {
println(compute())
}簡単な確認
suspend関数がdelay(5000)を呼び出します。runTestを使ったテストがほぼ瞬時に終了するのはなぜでしょうか。
まとめ
コルーチンを確実にテストできるようになりました。
runTestはsuspendコードを実行し、子コルーチンを待機します- 仮想時間によって遅延をスキップします。必要に応じて手動で時間を進めます
- ディスパッチャーを注入し、
setMain/resetMainを使用します - Flowは収集してテストします(またはTurbineを使用します)
これでTestingコースは完了です。
よくある質問
「コルーチンのテスト」レッスンは無料ですか?
はい。「コルーチンのテスト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「コルーチンのテスト」で何を学びますか?
suspend関数をテストします ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「コルーチンのテスト」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- JUnit5でテストを書く
- アサーション
- MockKによるモック
- コルーチンのテスト