Kotlin Multiplatform Help

Testing Compose Multiplatform UI

UI testing in Compose Multiplatform is implemented using the same finders, assertions, actions, and matchers as the Jetpack Compose testing API. If you're not familiar with them, read the Jetpack Compose guide before you continue with this article.

How Compose Multiplatform testing is different from Jetpack Compose

Compose Multiplatform common test API does not rely on JUnit's TestRule class. Instead, you call the runComposeUiTest function and invoke the test functions on the ComposeUiTest receiver.

However, JUnit-based API is available for desktop targets.

Writing and running tests with Compose Multiplatform

First, add the source set for tests and the necessary dependencies to the module. Then, write and run the example test and try to customize it.

Create the test source set and add the testing library to dependencies

To provide concrete examples, the instructions on this page follow the project structure generated by the Kotlin Multiplatform wizard. If you are adding tests to an existing project, you may have to replace shared in paths and commands with the module name you are testing.

When you check the Include tests option in the Kotlin Multiplatform wizard, it generates the basic structure for tests, including *Test source sets.

Set up the UI testing library: In the shared/build.gradle.kts file, add the UI testing library to dependencies of the commonTest source set.

kotlin { //... sourceSets { // Adds the common test dependency commonTest.dependencies { //... implementation("org.jetbrains.compose.ui:ui-test:1.11.0") } // Adds the desktop test dependency jvmTest.dependencies { implementation(compose.desktop.currentOs) } } }

If you need to run instrumented (emulator) tests for Android, amend your Gradle configuration as follows:

  1. In the shared/build.gradle.kts file, add the following code to the androidLibrary {} block to configure the instrumented test source set to depend on a common test source set.

    kotlin { //... androidLibrary { withDeviceTestBuilder { sourceSetTreeName = "test" } } }
  2. In the androidApp/build.gradle.kts file, add the following code to the android.defaultConfig {} block to configure the Android test instrumentation runner:

    android { //... defaultConfig { //... testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } }
  3. In the androidApp/build.gradle.kts file, add the required dependencies in the root dependencies {} block:

    dependencies { androidTestImplementation("androidx.compose.ui:ui-test-junit4-android:1.11.1") debugImplementation("androidx.compose.ui:ui-test-manifest:1.11.1") }
  4. Select Build | Sync Project with Gradle Files in the main menu, or click the Gradle refresh button in the build script editor.

  5. Remember to create the shared/src/androidDeviceTest source set for instrumented tests. Even if the bulk of your tests are in commonTest, the androidDeviceTest directory should have at least the AndroidManifest.xml file that points to the general activity that the tests will use:

    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application> <activity android:name="androidx.activity.ComponentActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

Now, you are ready to write and run common tests for the Compose Multiplatform UI.

Write and run common tests

In the shared/src/commonTest/kotlin/<package> directory, create a file named ExampleTest.kt and copy the following code into it:

import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.assertTextEquals import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.performClick import androidx.compose.ui.test.v2.runComposeUiTest import kotlin.test.Test class ExampleTest { @OptIn(ExperimentalTestApi::class) @Test fun myTest() = runComposeUiTest { // Declares a mock UI to demonstrate API calls // // Replace with your own declarations to test the code of your project setContent { var text by remember { mutableStateOf("Hello") } Text( text = text, modifier = Modifier.testTag("text") ) Button( onClick = { text = "Compose" }, modifier = Modifier.testTag("button") ) { Text("Click me") } } // Tests the declared UI with assertions and actions of the Compose Multiplatform testing API onNodeWithTag("text").assertTextEquals("Hello") onNodeWithTag("button").performClick() onNodeWithTag("text").assertTextEquals("Compose") } }

To run tests:

There are two options:

  • In IntelliJ IDEA, you can click the green run icon in the gutter next to the myTest() function, choose Run | ExampleTest.myTest, then select the iOS target for the test.

  • Run the following command in the terminal:

    ./gradlew :shared:iosSimulatorArm64Test

Run this command in the terminal:

./gradlew :shared:connectedAndroidTest

Currently, you cannot run common Compose Multiplatform tests using android (local) test configurations, so gutter icons in Android Studio, for example, won't be helpful.

You have two options:

  • Click the green run icon in the gutter next to the myTest() function and choose Run | ExampleTest.myTest, then select the JVM target.

  • Run the following command in the terminal:

    ./gradlew :shared:jvmTest

Run this command in the terminal:

./gradlew :shared:wasmJsTest

What's next

Now that you got the hang of Compose Multiplatform UI testing, you may want to check out more testing-related resources:

15 May 2026