https://kotlinlang.org logo
#compose
Title
# compose
z

ziv kesten

08/02/2022, 2:44 PM
I want to test a button that changes it's state on click to a progress indicator and then a few seconds later becomes disabled. How can i make the test wait or speed up to test the final state?
Copy code
@Test
    fun test_button_completed_state_correct(): Unit = runBlocking {

        val completedText = mockStateButtonsList.items.first().contents.first { it.state == StateButtonListContent.ButtonState.COMPLETED }.button.caption.orEmpty()

        // Given
        composeTestRule.setContent {
            TestStateButtonList(
                StateButtonListStateReducer(mockStateButtonsList, this)
            )
        }

        // When
        composeTestRule
            .onAllNodesWithTag(STATE_BUTTON)
            .onFirst()
            .performClick()

        // Wait 5000 milliseconds

        // Then
        composeTestRule
            .onAllNodesWithTag(STATE_BUTTON)
            .onFirst()
            .assert(hasText(completedText))
    }
l

Landry Norris

08/02/2022, 2:46 PM
You can use delay(Long) to delay a certain time. If I remember correctly, delay(Long) will cause other coroutines to immediately act like there was a delay.
this should help
Copy code
rule.mainClock.advanceTimeBy(DefaultDurationMillis.toLong())
can you use advanceTimeBy to test this ? 🤔
l

Landry Norris

08/02/2022, 2:48 PM
That looks cool. I didn’t know about rule.mainClock
o

oianmol

08/02/2022, 2:49 PM
Let me know if that worked for you!
z

ziv kesten

08/02/2022, 2:49 PM
mainClock.autoAdvance = false
failes the test
But
delay
worked
However, the test would be long (number of secondes i wait in delay)
l

Landry Norris

08/02/2022, 2:50 PM
after setting autoAdvance to false, did you use advanceTimeBy?
z

ziv kesten

08/02/2022, 2:51 PM
Yes, the test failed faster 🥲
Copy code
java.lang.AssertionError: Failed to assert the following: (Text + EditableText contains 'IN PROGRESS' (ignoreCase: false))
Semantics of the node:
Node #66 at (l=605.0, t=107.0, r=1033.0, b=258.0)px, Tag: 'test_button'
Role = 'Button'
Focused = 'false'
Text = '[CONNECT]'
Actions = [OnClick, GetTextLayoutResult]
MergeDescendants = 'true'
Has 11 siblings
Selector used: ((TestTag = 'test_button')[0])
l

Landry Norris

08/02/2022, 2:52 PM
If you use runTest {} instead of run blocking, delay will signal other coroutines, but not actually delay.
z

ziv kesten

08/02/2022, 2:53 PM
I have to use runBlocking because i need a couroutine scope to test with.
The button uses a coroutine scope internally
l

Landry Norris

08/02/2022, 2:53 PM
runBlockingTest?
z

ziv kesten

08/02/2022, 2:54 PM
Trying
l

Landry Norris

08/02/2022, 2:54 PM
runTest should provide a coroutine scope.
z

ziv kesten

08/02/2022, 2:55 PM
runBlockingTest
worked!!!
Thank you!!
s

Stylianos Gakis

08/02/2022, 9:30 PM
Wait where does
runBlockingTest
come from?
l

Landry Norris

08/02/2022, 9:31 PM
It’s in the coroutines test package. They do recommend replacing it with runTest where possible.
s

Stylianos Gakis

08/02/2022, 9:38 PM
Aha alright, that's the old API then I guess, I thought maybe it was coming from somewhere else.
7 Views