This guide explains how to set up unit tests for a Kotlin Multiplatform application using Compose and Robolectric.
Testing a Kotlin Multiplatform App with Compose and Robolectric
Why this is important:
- Shared code: Kotlin Multiplatform lets you share code between Android, iOS, Desktop, and Web.
- Efficient testing: Robolectric enables fast unit tests by simulating the Android environment on your development machine.
What you'll learn:
- How to configure a Kotlin Multiplatform project for testing.
- How to write instrumented tests that run on a real Android device or emulator.
- How to write unit tests using Robolectric and JUnit 5.
- How to increase code coverage with Kover.
Steps:
-
Project Setup:
-
Create a
commonTest
directory in yourcomposeApp
module. -
Add the following dependencies to your
build.gradle.kts
:kotlin { sourceSets { commonTest.dependencies { implementation(kotlin("test")) implementation(compose.uiTest) } androidInstrumentedTest.dependencies { implementation(compose.uiTest) } } androidTarget { instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree.test) dependencies { debugImplementation(libs.androidx.ui.test.manifest) } } } android { defaultConfig { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } }
-
-
Write a Simple Test:
-
Create a test file (e.g.,
AppTest.kt
) incommonTest
. -
Write a test using
runComposeUiTest
to interact with a Compose component:class AppTest: UsingContext() { @Test fun myTest() = runComposeUiTest { setContent { MaterialTheme { App() } } onNodeWithText("Click me!").performClick() } }
-
-
Run Instrumented Test:
- Launch an Android emulator.
- Run the test:
./gradlew composeApp:connectedAndroidTest
-
Add Robolectric and JUnit 5:
- Upgrade to Kotlin 2.1.0.
- Add the Robolectric plugin and dependencies.
- Apply the plugin in your
build.gradle.kts
.
-
Create and Implement
UsingContext
:- Create an
expect
class namedUsingContext
incommonTest
. - Implement the
actual
class for Android inandroidTest
, configuring Robolectric. - Implement empty
actual
classes for other platforms (iOS, Desktop, Web).
- Create an
-
Add an Activity to the Manifest:
- Add an empty
ComponentActivity
to yourAndroidManifest.xml
.
- Add an empty
-
Run Robolectric Tests:
- Run:
./gradlew composeApp:testDebugUnitTest
- Run:
-
Exclude
UsingContext
fromcheck
Task:-
Prevent JUnit5 from misinterpreting
UsingContext
as a test class:tasks.withType<Test>().configureEach { exclude("fr/pitdev/article/kmtest/utils/UsingContext.class") }
-
Run the check task:
./gradlew check
-
Bonus: Code Coverage with Kover
- Add Kover dependencies and plugin.
- Apply the plugin and configure Kover in your
build.gradle.kts
. - Generate an HTML report:
gradlew koverHtmlReport
Learn More: