0Pricing
Kotlin Academy · Урок

Тестирование сопрограмм

Тестируйте приостанавливаемые функции

«Тестирование сопрограмм» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Почему тестирование сопрограмм особенное

Сопрограммы выполняются асинхронно и могут использовать задержки. Тестам нужны контролируемое время и способ дождаться завершения приостанавливаемых функций.

Библиотека 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), а после этого сбросьте замену.

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()

Тестирование приостанавливаемой функции

Приостанавливаемую функцию можно напрямую вызвать и проверить внутри runTest.

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 и проверьте их. Библиотека Turbine особенно упрощает тестирование потоков.

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 связывает приостанавливаемый код с обычной функцией main. Это показывает приостанавливаемую функцию, которую необходимо протестировать.

import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.delay

suspend fun compute(): Int { delay(100); return 42 }

fun main() = runBlocking {
    println(compute())
}

Быстрая проверка

Приостанавливаемая функция вызывает delay(5000). Почему тест с использованием runTest завершается почти мгновенно?

Повторение

Вы умеете надёжно тестировать сопрограммы:

  • runTest выполняет приостанавливаемый код и дожидается дочерних сопрограмм
  • Виртуальное время пропускает задержки; при необходимости продвигайте его вручную
  • Внедряйте диспетчеры; используйте setMain/resetMain
  • Тестируйте потоки, собирая их значения (или с помощью Turbine)

На этом курс по тестированию завершен.

Часто задаваемые вопросы

Урок «Тестирование сопрограмм» бесплатный?

Да — полный текст урока «Тестирование сопрограмм» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Тестирование сопрограмм»?

Тестируйте приостанавливаемые функции Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Тестирование сопрограмм»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Написание тестов с JUnit5
  2. Проверки
  3. Имитация с MockK
  4. Тестирование сопрограмм
← Назад к Kotlin Academy