Lincheck в проектах Kotlin Multiplatform
Lincheck можно использовать с Kotlin Multiplatform для тестирования кода, предназначенного для JVM. В этой статье вы узнаете, как настроить тесты Lincheck в проекте Kotlin Multiplatform.
Вы:
Настроите проект для запуска тестов Lincheck на платформах, использующих JVM.
Создадите классы структур данных-счетчиков, общие для всех платформ.
Создадите общие для всех платформ тесты счетчиков, а также тесты, предназначенные только для JVM.
Запустите тесты.
Настройка проекта
-
Создайте новый проект Kotlin Multiplatform в IntelliJ IDEA. При создании проекта убедитесь, что:
Установлен флажок Include tests.
-
В проекте есть цель на базе JVM (серверная, настольная или Android). Проверить, что код компилируется для JVM, можно, просмотрев файл
shared/build.gradle.ktsилиcore/build.gradle.kts:kotlin { // ... jvm() // ... // If you have an Android target, the use of JVM is // configured in the `androidLibrary` section androidLibrary { // ... compilerOptions { jvmTarget = JvmTarget.JVM_11 } // ... } }
-
Настройте папку для тестов и зависимость Lincheck в соответствии с целевыми платформами проекта:
Desktop/Android + iOS
Каталог для тестов, предназначенных для конкретной платформы, автоматически создается плагином Kotlin Multiplatform. Например, для настольной цели это shared/src/jvmTest/kotlin.
Добавьте зависимость Lincheck для платформенного набора исходного кода для тестов и зависимость kotlin.test для набора исходного кода commonTest:
// shared/build.gradle.kts
kotlin {
sourceSets {
commonTest.dependencies {
implementation(libs.kotlin.test)
}
jvmTest {
implementation("org.jetbrains.lincheck:lincheck:3.7")
}
}
}
// shared/build.gradle.kts
kotlin {
sourceSets {
commonTest.dependencies {
implementation(libs.kotlin.test)
}
getByName("androidHostTest").dependencies {
implementation("org.jetbrains.lincheck:lincheck:3.7")
}
}
}
Server + iOS, Server + Desktop, Server + Desktop + iOS
-
Создайте каталог
core/src/jvmTest/kotlin. Gradle будет запускать тесты в этом каталоге для всех платформ, использующих JVM.В проектах с настольной целью также есть каталог
shared/src/jvmTest/kotlin, который можно использовать вместо него. Однако рекомендуется размещать код, относящийся как к серверной, так и к настольной целям/iOS, в каталогеcore.Если у вас есть настольная цель и вы создаете каталог
core/src/jvmTest/kotlin, удалите каталогshared/src/jvmTest/kotlin. -
Добавьте зависимость Lincheck для набора исходного кода
jvmTestи зависимостьkotlin.testдля набора исходного кодаcommonTest:// core/build.gradle.kts kotlin { // ... sourceSets { // ... commonTest.dependencies { implementation(libs.kotlin.test) } jvmTest.dependencies { implementation("org.jetbrains.lincheck:lincheck:3.7") } } }
Создание общих классов
Создайте классы, реализующие структуры данных-счетчики, общие для всех платформ:
-
Создайте файл
UnsafeCounter.ktв каталогеcore/src/commonMainилиshared/src/commonMain:class UnsafeCounter { private var value: Int = 0 fun inc() = value++ fun get(): Int = value } -
Создайте файл
SafeCounter.ktв том же каталоге:import kotlin.concurrent.atomics.AtomicInt import kotlin.concurrent.atomics.ExperimentalAtomicApi @OptIn(ExperimentalAtomicApi::class) class SafeCounter { private var value = AtomicInt(0) fun inc() = value.addAndFetch(1) fun get(): Int = value.load() }
Написание общих тестов
Напишите тесты, которые запускаются для всех платформ:
-
Создайте файл
UnsafeCounterTest.ktв каталогеcore/src/commonTestилиshared/src/commonTest:import kotlin.test.Test import kotlin.test.assertEquals class UnsafeCounterTest { @Test fun testIncrement() { val counter = UnsafeCounter() assertEquals(0, counter.get(), "Initial value should be 0") counter.inc() assertEquals(1, counter.get(), "Value after one increment should be 1") } } -
Создайте файл
SafeCounterTest.ktв том же каталоге:import kotlin.test.Test import kotlin.test.assertEquals class SafeCounterTest { @Test fun testIncrement() { val counter = SafeCounter() assertEquals(0, counter.get(), "Initial value should be 0") counter.inc() assertEquals(1, counter.get(), "Value after one increment should be 1") } }
Написание тестов для JVM
Напишите тесты, которые запускаются только на платформах, предназначенных для JVM:
-
Создайте файл
UnsafeCounterConcurrentTest.ktв каталоге тестов для тестов, предназначенных только для JVM:Android + iOS —
shared/src/androidHostTest/kotlinDesktop + iOS —
shared/src/jvmTest/kotlinЛюбой проект с серверной целью —
core/src/jvmTest/kotlin
import org.jetbrains.lincheck.datastructures.ModelCheckingOptions import org.jetbrains.lincheck.datastructures.Operation import kotlin.test.Test class UnsafeCounterConcurrentTest { private val c = UnsafeCounter() @Operation fun inc() = c.inc() @Operation fun get() = c.get() @Test fun modelCheckingTest() { ModelCheckingOptions().check(this::class) } } -
Создайте файл
SafeCounterConcurrentTest.ktв том же каталоге:import org.jetbrains.lincheck.datastructures.ModelCheckingOptions import org.jetbrains.lincheck.datastructures.Operation import kotlin.test.Test class SafeCounterConcurrentTest { private val c = SafeCounter() @Operation fun inc() = c.inc() @Operation fun get() = c.get() @Test fun modelCheckingTest() { ModelCheckingOptions().check(this::class) } }
Запуск тестов
На этом этапе в проекте должны быть общая реализация структур данных-счетчиков, общие тесты и тесты счетчиков, предназначенные только для JVM. Структура каталогов проекта должна выглядеть так:




Можно запускать отдельные тесты из контекстного меню, с помощью сочетания клавиш или запустив задачу Gradle. Если запустить задачу Gradle allTests, будут выполнены все тесты проекта с помощью соответствующего средства запуска тестов:
Например, тесты, предназначенные только для JVM, выполняются с помощью средства запуска тестов JVM:
Поддержка платформ, отличных от JVM
Маловероятно, что в будущем Lincheck будет поддерживать другие платформы.
Lincheck в значительной степени полагается на JVM для манипуляций с байт-кодом, что затрудняет реализацию модельной проверки на других платформах. Кроме того, одновременное применение модельной проверки для нескольких платформ не дает существенных преимуществ, поскольку Lincheck тестирует код в детерминированной изолированной среде, и результаты тестов не зависят от платформы.
См. также
Узнайте больше о Kotlin Multiplatform
Ознакомьтесь с документацией Lincheck
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/lincheck-kmp.html