Testing Forms & User Inputs
This guide covers how to test interactive Compose UI components, text inputs, keyboard entry, and explicit Modifier.testTag identifiers using Parikshan.
Sample Repository Branch:
All code in this guide is available on thefeature/greeting-formbranch:
github.com/aryapreetam/parikshan-kmp-sample/tree/feature/greeting-form
Quick Setup: Switch or Clone Branch
If you followed Your First Test, switch to the greeting form branch:
Or clone the branch directly into a new directory:
1. Add Test Tags to Your UI Component
Open shared/src/commonMain/kotlin/org/parikshankmpsample/App.kt and define an interactive greeting screen. Use Modifier.testTag(...) to give interactive UI elements stable identifiers for automated testing:
package org.parikshankmpsample
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.ui.tooling.preview.Preview
@Composable
@Preview
fun App() {
MaterialTheme {
var name by remember { mutableStateOf("") }
var greeting by remember { mutableStateOf("") }
Column(
modifier = Modifier.fillMaxSize().padding(all = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("Enter your name") },
modifier = Modifier.testTag("name_input") // (1)
)
Button(
onClick = { greeting = "Hello, $name!" },
modifier = Modifier.padding(top = 16.dp).testTag("greet_button") // (2)
) {
Text("Greet")
}
if (greeting.isNotEmpty()) {
Text(
text = greeting,
modifier = Modifier.padding(top = 24.dp).testTag("greeting_text") // (3)
)
}
}
}
}
Modifier.testTag("name_input"): Identifies the text field for typing input.Modifier.testTag("greet_button"): Identifies the button for click interactions.Modifier.testTag("greeting_text"): Identifies the result label for visibility assertions.


App.kt2. Write the Form E2E Test
Create a new Kotlin test class inside commonTest:
shared/src/commonTest/kotlin/org/parikshankmpsample/SimpleGreetTest.kt
package org.parikshankmpsample
import io.github.aryapreetam.parikshan.e2eTest
import kotlin.test.Test
class SimpleGreetTest {
@Test
fun testGreetingFlow() = e2eTest {
// Step 1: Type the name into the input field
input("name_input", "Parikshan") // (1)
// Step 2: Click the Greet button
click("Greet") // (2)
// Step 3: Assert the greeting text is displayed
assertVisible("Hello, Parikshan!") // (3)
}
}
input("name_input", ...): Locates the text field by itsModifier.testTag("name_input")and simulates realistic character-by-character typing.click("Greet"): Matches the button by its rendered text"Greet"and executes a tap.assertVisible("Hello, Parikshan!"): Verifies that the dynamic greeting text is rendered in the UI hierarchy.
You can run your form test on Desktop JVM in either of the following ways:
- From IDE: Open the Gradle tool window on the right, navigate to
shared > Tasks > verification(orTasks > verification), and double-clicke2eJvmTest(or right-clickSimpleGreetTest.ktand select Run 'SimpleGreetTest'). - From Terminal: Run:


SimpleGreetTest.kt open in IDE3. Run Across Targets
You can execute the exact same form test suite across all configured target platforms concurrently:
- From IDE: Open the Gradle tool window under
shared > Tasks > verification(orTasks > verification), double-clicke2eTest(or right-click → Run). - From Terminal: Run:
Visual Demo: Concurrent Multi-Target Test Execution
4. Selector Best Practices
Parikshan's selector engine evaluates target elements using a multi-tiered resolution pipeline:
- Explicit Test Tags: Target using
Modifier.testTag("my_tag")→click("my_tag")orinput("my_tag", ...). - Text Content: Target visible text directly →
click("Submit")orassertVisible("Welcome back"). - Content Descriptions: Target accessibility labels →
click("Close dialog").
Tip
Use visible text selectors for standard buttons and headers to keep your test code readable and close to user intent. Use Modifier.testTag for input fields or icon-only buttons that lack visible text labels.