-
Notifications
You must be signed in to change notification settings - Fork 0
Test UI
Ali Sadeghi edited this page Feb 5, 2026
·
7 revisions
Generates Compose UI tests using runComposeUiTest.
Spawned by: Feature-Test command
Tests ALWAYS target {Feature}ScreenRoot, not {Feature}Screen.
ScreenRoot is ViewModel-independent and takes UiState + callbacks directly, making it testable without mocking.
// Screen - ViewModel wrapper (NOT TESTED DIRECTLY)
@Composable
fun LoginScreen(viewModel: LoginViewModel = koinViewModel(), ...)
// ScreenRoot - ViewModel-independent (THIS IS TESTED)
@Composable
fun LoginScreenRoot(uiState: LoginUiModel, onLogin: () -> Unit, onRetry: () -> Unit, ...)- State rendering (all 4 states: Uninitialized, Loading, Success, Failed)
- User interactions (button clicks, text input)
- Callback invocations (onRetry, onBackClick, onItemClick)
- Accessibility (content descriptions)
- Error message display using actual ErrorConst messages
@OptIn(ExperimentalTestApi::class)
class LoginScreenTest {
@Test
fun `shows loading indicator when state is Loading`() = runComposeUiTest {
setContent {
MaterialTheme {
LoginScreenRoot(
uiState = LoginUiFixtures.createLoadingState(),
onLogin = {},
onRetry = {},
onBackClick = {}
)
}
}
onNodeWithContentDescription("Loading").assertExists()
}
@Test
fun `shows network error message and retry button`() = runComposeUiTest {
setContent {
LoginScreenRoot(
uiState = LoginUiFixtures.createNetworkErrorState(),
onLogin = {},
onRetry = {},
onBackClick = {}
)
}
// ErrorConst.NoNetwork message
onNodeWithText("Error, Check your connection and try again.", substring = true).assertIsDisplayed()
onNodeWithText("Retry").assertIsDisplayed()
}
@Test
fun `retry button invokes onRetry callback`() = runComposeUiTest {
var retryCalled = false
setContent {
LoginScreenRoot(
uiState = LoginUiFixtures.createNetworkErrorState(),
onLogin = {},
onRetry = { retryCalled = true },
onBackClick = {}
)
}
onNodeWithText("Retry").performClick()
assertTrue(retryCalled)
}
@Test
fun `shows content when state is Success`() = runComposeUiTest {
setContent {
MaterialTheme {
LoginScreenRoot(
uiState = LoginUiFixtures.createSuccessState(),
onLogin = {},
onRetry = {},
onBackClick = {}
)
}
}
onNodeWithText("Welcome").assertIsDisplayed()
}
}All UI tests use {Feature}UiFixtures for consistent state creation:
// Create specific states for testing
LoginUiFixtures.createLoadingState()
LoginUiFixtures.createSuccessState()
LoginUiFixtures.createNetworkErrorState() // Uses ErrorConst message
LoginUiFixtures.createUnauthorizedErrorState()Back to Testing-Agents | Agents