valentinilk / compose-shimmer

A simple shimmer library for Jetpack Compose.
https://valentinilk.github.io/compose-shimmer/
Apache License 2.0
673 stars 37 forks source link

Test takes a very long time to return result #10

Closed hoboris closed 1 year ago

hoboris commented 2 years ago

Hey Valentin! I'm implementing unit tests for my Composables that use your shimmer, but they are not passing within a reasonable time. When Modifier.shimmer() is called, unit tests seems to continue running for a while, then eventually finishes after a very long time.

Given the following Activity:

class ShimmerActivity : AppCompatActivity()  {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .shimmer()
                    .background(Color.White)
            )
        }
    }
}

And the following test :

@RunWith(RobolectricTestRunner::class)
class ShimmerActivityTest {

    @Test
    fun shimmer_activity_test() {
        launchActivity<ShimmerActivity>().onActivity {
            assertTrue(true)
        }
    }
}

The test only passes after more than 2 hours.

image

But when //.shimmer() is commented out, then the test passes as expected after a few seconds.

image

valentinilk commented 2 years ago

Hey @hoboris, this is probably caused by the LaunchedEffect that is hidden inside the shimmer modifier.

I'm not familiar with Robolectric, but could get it to work by disabling the automatic clock synchronization between the tests and compose UI (Jetpack Documentation - Disable Autosync).

import androidx.compose.ui.test.junit4.createAndroidComposeRule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import androidx.test.core.app.launchActivity
import org.junit.Rule
import org.robolectric.annotation.LooperMode

@RunWith(RobolectricTestRunner::class)
class MainActivityTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<MainActivity>()

    @Test
    @LooperMode(LooperMode.Mode.PAUSED)
    fun testShimmer() {
        composeTestRule.mainClock.autoAdvance = false
        launchActivity<MainActivity>().onActivity {
            assert(true)
        }
    }
}

I'm not sure if that is the way to go with Robolectric, but I hope it helps. Let me know if I can close this issue. :)