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 composeApp
in paths and commands with the module name you are testing (shared
, for example).
Create a common test source set and add the necessary dependencies:
Create a directory for the common test source set:
composeApp/src/commonTest/kotlin
.In the
composeApp/build.gradle.kts
file, add the following dependencies:kotlin { //... sourceSets { val desktopTest by getting // Adds common test dependencies commonTest.dependencies { implementation(kotlin("test")) @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) implementation(compose.uiTest) } // Adds the desktop test dependency desktopTest.dependencies { implementation(compose.desktop.currentOs) } } }If you need to run instrumented (emulator) tests for Android, amend your Gradle configuration further:
Add the following code to the
androidTarget {}
block and follow IDE's suggestions to add missing imports:kotlin { //... androidTarget { @OptIn(ExperimentalKotlinGradlePluginApi::class) instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree.test) //... } //... }Add the following code to the
android.defaultConfig {}
block:android { //... defaultConfig { //... testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } }Add the following code to the config top level:
//https://developer.android.com/develop/ui/compose/testing#setup dependencies { androidTestImplementation("androidx.compose.ui:ui-test-junit4-android:1.6.8") debugImplementation("androidx.compose.ui:ui-test-manifest:1.6.8") }
Now, you are ready to write and run common tests for the Compose Multiplatform UI.
Write and run common tests
In the composeApp/src/commonTest/kotlin
directory, create a file named ExampleTest.kt
and copy the following code into it:
To run tests:
You have two options:
In Android Studio and Fleet, you can click the green run icon in the gutter next to the
myTest()
function, choose Run and the iOS target for the test.Run the following command in the terminal:
./gradlew :composeApp:iosSimulatorArm64Test
Run this command in the terminal:
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 | desktop.Run the following command in the terminal:
./gradlew :composeApp:desktopTest
Run this command in the terminal:
Running JUnit-based tests for desktop targets
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 composeApp
in paths and commands with the module name you are testing (shared
, for example).
Create the test source set and add the necessary dependencies:
Create a directory for tests:
composeApp/src/desktopTest/kotlin
.In the
composeApp/build.gradle.kts
file, add the following dependencies:kotlin { //... sourceSets { //... val desktopTest by getting { dependencies { implementation(compose.desktop.uiTestJUnit4) implementation(compose.desktop.currentOs) } } } }Create a test file called
ExampleTest.kt
and copy the following code into it:import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.test.* import androidx.compose.ui.platform.testTag import androidx.compose.ui.test.junit4.createComposeRule import org.junit.Rule import org.junit.Test class ExampleTest { @get:Rule val rule = createComposeRule() @Test fun myTest(){ // Declares a mock UI to demonstrate API calls // // Replace with your own declarations to test the code in your project rule.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 JUnit-based testing API rule.onNodeWithTag("text").assertTextEquals("Hello") rule.onNodeWithTag("button").performClick() rule.onNodeWithTag("text").assertTextEquals("Compose") } }To run the test, click the run icon in the gutter next to the
myTest()
function or run the following command in the terminal:./gradlew desktopTest
What's next
Now that you got the hang of Compose Multiplatform UI testing, you may want to check out more testing-related resources:
For a general overview of testing in a Kotlin Multiplatform project, see Understand basic project structure and the Test your multiplatform app tutorial.
More advanced testing in Android Studio, including automation, is covered in the Test your app article on the Android for Developers portal.