Compose Test is Flaky

457 Views Asked by At

My some view that starts from an activity shows an alert dialog when pressing the back button using the BackHandler.

@Composable
fun PostEditContent(
    title: String,
    uiState: BasePostEditUiState
) {
    var enabledBackHandler by remember { mutableStateOf(true) }
    var enabledAlertDialog by remember { mutableStateOf(false) }
    val snackBarHostState = remember { SnackbarHostState() }
    val coroutineScope = rememberCoroutineScope()

    val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
    val navigateToBack = { onBackPressedDispatcher?.onBackPressed() }
    val forceNavigateToBack = {
        coroutineScope.launch {
            enabledBackHandler = false
            awaitFrame()
            navigateToBack()
        }
    }

    if (enabledAlertDialog) {
        PostEditAlertDialog(
            onDismissRequest = { enabledAlertDialog = false },
            onOkClick = { forceNavigateToBack() }
        )
    }

    BackHandler(enabledBackHandler) {
        enabledAlertDialog = true
    }

    ...

It's working fine. But in the testing, it sometimes failed because the awaitFrame() is not working properly.

@Suppress("TestFunctionName")
@Composable
private fun PostEditScreenWithHomeBackStack(uiState: PostEditUiState) {
    val navController = rememberNavController()

    NavHost(navController, startDestination = "home") {
        composable(route = "home") {
            Text(HOME_STACK_TEXT)
        }
        composable(route = "edit") {
            PostEditScreen(uiState = uiState)
        }
    }
    SideEffect {
        navController.navigate("edit")
    }
}

...

@Test
fun navigateToUp_WhenSuccessSaving() {
    composeTestRule.apply {
        setContent {
            PostEditScreenWithHomeBackStack(emptyUiState.copy(title = "a", content = "a"))
        }

        // The save button calls the `forceNavigateToBack()` that in the upper code block
        onNodeWithContentDescription("save").performClick()

        onNodeWithText(HOME_STACK_TEXT).assertIsDisplayed()
    }
}

Is there a better way to show the alert dialog or fix the flaky test? Thanks.

0

There are 0 best solutions below