Hi, im creating Android compose UI tests and want ...
# compose
t
Hi, im creating Android compose UI tests and want to use turbine to collect my viewModel state and check my Compose UI reacts correctly, firstly, is this a valid test to create? and secondly How do you do it? 😄
My test lookslike this
Copy code
@Test
fun dishwasherDetailsMainScreen_loadingToData_showsLoadingThenDetails() = runTest {
    val testDispatcher = StandardTestDispatcher(testScheduler)
    val fakeDataSource = FakeDishwasherDataSource(details = sampleDishwasherDetail)
    val useCase = GetDishwasherDetailUseCase(fakeDataSource)
    val viewModel = DishwasherDetailViewModel(useCase, testDispatcher)

    // Set Compose content
    composeTestRule.setContent {
        DishwasherTheme {
            CompositionLocalProvider(LocalBackButtonVisibility provides true) {
                DishwasherDetailsMainScreen(
                    viewModel = viewModel,
                    dishwasherDetail = dishwasherDetailInput,
                    onBack = {}
                )
            }
        }
    }

    // Start Turbine collection of the ViewModel flow
    viewModel.uiState.test {
        // 1️⃣ Initial state
        assertEquals(UiState.Initial, awaitItem())

        // Trigger load
        viewModel.loadDishwasherDetails(dishwasherDetailInput)

        // Advance dispatcher so Loading is emitted
        testScheduler.advanceUntilIdle()

        // 2️⃣ Loading state
        assertEquals(UiState.Loading, awaitItem())

        // Now Compose should have recomposed for loading state
        composeTestRule.onNodeWithText(
            composeTestRule.activity.getString(R.string.loading_dishwasher)
        ).assertIsDisplayed()

        // 3️⃣ Data state
        val dataState = awaitItem() as UiState.Data
        val item = dataState.data

        // Let Compose recompose with Data
        testScheduler.advanceUntilIdle()

        // Assert Compose UI shows data
        composeTestRule.onNodeWithText(item.title)
            .assertIsDisplayed()

        cancelAndIgnoreRemainingEvents()
    }
}
the turbine checks work ok, when i add the Compose node checks I do not see loading, I guess its because in my compose components i collect viewmodel state like this v`al uiState by viewModel.uiState.collectAsStateWithLifecycle(),` how do i "increment" lisfecycle?
a
Do a collectAsState, then it doesn't need to know about lifecycle, and see if thats the actual issue here, could be smth else.
🙌 1
I usually test state changes and composables separately, i think its more straightforward/easier.
t
No, that didnt work 😞
z
I don't understand why you'd need Turbine if you're trying to validate compose ui. Turbine is great for testing flows on their own: it gives you a way to conveniently assert on emissions. If you're testing Compose UI, that has its own interaction with flows and you'd just use the compose rule to assert on ui state. It would make sense to use Turbine to test your VM flows on their own, and then use a compose UI test rule to test how your UI responds to flow emissions (probably with a faked out VM since you're using turbine to test the vm itself), but as separate tests.