ComposeUiTest

Known direct subclasses
AndroidComposeUiTest

Variant of ComposeUiTest for when you want to have access to the current activity of type A.

DesktopComposeUiTest

A test environment that allows you to test and control composables, either in isolation or in applications. Most of the functionality in this interface provides some form of test synchronization: the test will block until the app or composable is idle, to ensure the tests are deterministic.

For example, if you would perform a click on the center of the screen while a button is animating from left to right over the screen, without synchronization the test would sometimes click when the button is in the middle of the screen (button is clicked), and sometimes when the button is past the middle of the screen (button is not clicked). With synchronization, the app would not be idle until the animation is over, so the test will always click when the button is past the middle of the screen (and not click it). If you actually do want to click the button when it's in the middle of the animation, you can do so by controlling the clock. You'll have to disable automatic advancing, and manually advance the clock by the time necessary to position the button in the middle of the screen.

To test a composable in isolation, use setContent to set the composable in a host. On Android, a host will mostly be an Activity. When using runComposeUiTest or any of its platform specific friends, the host will be started for you automatically, unless otherwise specified. To test an application, use the platform specific variant of runComposeUiTest that launches the app.

An instance of ComposeUiTest can be obtained through runComposeUiTest or any of its platform specific variants, the argument to which will have it as the receiver scope.

Summary

Public functions

suspend Unit

Suspends until compose is idle.

Cmn
android
Unit

Registers an IdlingResource in this test.

Cmn
android
T
<T : Any?> runOnIdle(action: () -> T)

Executes the given action in the same way as runOnUiThread but waits until the app is idle before executing the action.

Cmn
android
T
<T : Any?> runOnUiThread(action: () -> T)

Runs the given action on the UI thread.

Cmn
android
Unit
setContent(composable: @Composable () -> Unit)

Sets the given composable as the content to be tested.

Cmn
android
Unit

Unregisters an IdlingResource from this test.

Cmn
android
Unit

Waits for compose to be idle.

Cmn
android
Unit
waitUntil(
    conditionDescription: String?,
    timeoutMillis: Long,
    condition: () -> Boolean
)

Blocks until the given condition is satisfied.

Cmn
android

Public properties

Density

Current device screen's density.

Cmn
android
MainTestClock

Clock that drives frames and recompositions in compose tests.

Cmn
android

Extension functions

Unit

Blocks until at least one node matches the given matcher.

Cmn
Unit

Blocks until no nodes match the given matcher.

Cmn
Unit

Blocks until exactly one node matches the given matcher.

Cmn
Unit
@ExperimentalTestApi
ComposeUiTest.waitUntilNodeCount(
    matcher: SemanticsMatcher,
    count: Int,
    timeoutMillis: Long
)

Blocks until the number of nodes matching the given matcher is equal to the given count.

Cmn

Inherited functions

From androidx.compose.ui.test.SemanticsNodeInteractionsProvider
SemanticsNodeInteractionCollection
onAllNodes(matcher: SemanticsMatcher, useUnmergedTree: Boolean)

Finds all semantics nodes that match the given condition.

android
SemanticsNodeInteractionCollection
onAllNodes(matcher: SemanticsMatcher, useUnmergedTree: Boolean)

Finds all semantics nodes that match the given condition.

Cmn
SemanticsNodeInteractionCollection
onAllNodes(matcher: SemanticsMatcher, useUnmergedTree: Boolean)

Finds all semantics nodes that match the given condition.

android
SemanticsNodeInteraction
onNode(matcher: SemanticsMatcher, useUnmergedTree: Boolean)

Finds a semantics node that matches the given condition.

android
SemanticsNodeInteraction
onNode(matcher: SemanticsMatcher, useUnmergedTree: Boolean)

Finds a semantics node that matches the given condition.

Cmn
SemanticsNodeInteraction
onNode(matcher: SemanticsMatcher, useUnmergedTree: Boolean)

Finds a semantics node that matches the given condition.

android

Public functions

awaitIdle

suspend fun awaitIdle(): Unit

Suspends until compose is idle. If auto advancement is enabled on the mainClock, this method will actively advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced actively which usually means that the Compose UI appears to be frozen. This is ideal for testing animations in a deterministic way. In either case, this method will wait for all IdlingResources to become idle.

Note that some processes are driven by the host operating system and will therefore still execute when auto advancement is disabled. For example, on Android measure, layout and draw can still happen if the host view is invalidated by other parts of the View hierarchy.

registerIdlingResource

fun registerIdlingResource(idlingResource: IdlingResource): Unit

Registers an IdlingResource in this test.

runOnIdle

fun <T : Any?> runOnIdle(action: () -> T): T

Executes the given action in the same way as runOnUiThread but waits until the app is idle before executing the action. This is the recommended way of doing your assertions on shared variables.

This method blocks until the action is complete.

runOnUiThread

fun <T : Any?> runOnUiThread(action: () -> T): T

Runs the given action on the UI thread.

This method blocks until the action is complete.

setContent

fun setContent(composable: @Composable () -> Unit): Unit

Sets the given composable as the content to be tested. This should be called exactly once per test.

Throws
kotlin.IllegalStateException

if called more than once per test, or if the implementation doesn't have access to a host to set content in.

unregisterIdlingResource

fun unregisterIdlingResource(idlingResource: IdlingResource): Unit

Unregisters an IdlingResource from this test.

waitForIdle

fun waitForIdle(): Unit

Waits for compose to be idle. If auto advancement is enabled on the mainClock, this method will actively advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced actively which usually means that the Compose UI appears to be frozen. This is ideal for testing animations in a deterministic way. In either case, this method will wait for all IdlingResources to become idle.

Note that some processes are driven by the host operating system and will therefore still execute when auto advancement is disabled. For example, on Android measure, layout and draw can still happen if the host view is invalidated by other parts of the View hierarchy.

waitUntil

fun waitUntil(
    conditionDescription: String? = null,
    timeoutMillis: Long,
    condition: () -> Boolean
): Unit

Blocks until the given condition is satisfied.

If auto advancement is enabled on the mainClock, this method will actively advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced actively which usually means that the Compose UI appears to be frozen. This is ideal for testing animations in a deterministic way. In either case, this method will wait for all IdlingResources to become idle.

Note that some processes are driven by the host operating system and will therefore still execute when auto advancement is disabled. For example, on Android measure, layout and draw can still happen if the host view is invalidated by other parts of the View hierarchy.

Compared to MainTestClock.advanceTimeUntil, waitUntil sleeps after every iteration to give the host operating system the opportunity to do measure/layout/draw passes. This gives waitUntil a better integration with the host, but it is less preferred from a performance viewpoint. Therefore, we recommend that you try using MainTestClock.advanceTimeUntil before resorting to waitUntil.

Parameters
conditionDescription: String? = null

An optional human-readable description of condition that will be included in the timeout exception if thrown.

timeoutMillis: Long

The time after which this method throws an exception if the given condition is not satisfied. This observes wall clock time, not frame time.

condition: () -> Boolean

Condition that must be satisfied in order for this method to successfully finish.

Throws
androidx.compose.ui.test.ComposeTimeoutException

If the condition is not satisfied after timeoutMillis (in wall clock time).

Public properties

density

val densityDensity

Current device screen's density. Note that it is technically possible for a Compose hierarchy to define a different density for a certain subtree. Try to use LayoutInfo.density where possible, which can be obtained from SemanticsNode.layoutInfo.

mainClock

val mainClockMainTestClock

Clock that drives frames and recompositions in compose tests.

Extension functions

waitUntilAtLeastOneExists

@ExperimentalTestApi
fun ComposeUiTest.waitUntilAtLeastOneExists(
    matcher: SemanticsMatcher,
    timeoutMillis: Long
): Unit

Blocks until at least one node matches the given matcher.

Parameters
matcher: SemanticsMatcher

The matcher that will be used to filter nodes.

timeoutMillis: Long

The time after which this method throws an exception if no nodes match the given matcher. This observes wall clock time, not frame time.

Throws
androidx.compose.ui.test.ComposeTimeoutException

If no nodes match the given matcher after timeoutMillis (in wall clock time).

See also
waitUntil

waitUntilDoesNotExist

@ExperimentalTestApi
fun ComposeUiTest.waitUntilDoesNotExist(
    matcher: SemanticsMatcher,
    timeoutMillis: Long
): Unit

Blocks until no nodes match the given matcher.

Parameters
matcher: SemanticsMatcher

The matcher that will be used to filter nodes.

timeoutMillis: Long

The time after which this method throws an exception if any nodes match the given matcher. This observes wall clock time, not frame time.

Throws
androidx.compose.ui.test.ComposeTimeoutException

If any nodes match the given matcher after timeoutMillis (in wall clock time).

See also
waitUntil

waitUntilExactlyOneExists

@ExperimentalTestApi
fun ComposeUiTest.waitUntilExactlyOneExists(
    matcher: SemanticsMatcher,
    timeoutMillis: Long
): Unit

Blocks until exactly one node matches the given matcher.

Parameters
matcher: SemanticsMatcher

The matcher that will be used to filter nodes.

timeoutMillis: Long

The time after which this method throws an exception if exactly one node does not match the given matcher. This observes wall clock time, not frame time.

Throws
androidx.compose.ui.test.ComposeTimeoutException

If exactly one node does not match the given matcher after timeoutMillis (in wall clock time).

See also
waitUntil

waitUntilNodeCount

@ExperimentalTestApi
fun ComposeUiTest.waitUntilNodeCount(
    matcher: SemanticsMatcher,
    count: Int,
    timeoutMillis: Long
): Unit

Blocks until the number of nodes matching the given matcher is equal to the given count.

Parameters
matcher: SemanticsMatcher

The matcher that will be used to filter nodes.

count: Int

The number of nodes that are expected to be matched.

timeoutMillis: Long

The time after which this method throws an exception if the number of nodes that match the matcher is not count. This observes wall clock time, not frame time.

Throws
androidx.compose.ui.test.ComposeTimeoutException

If the number of nodes that match the matcher is not count after timeoutMillis (in wall clock time).

See also
waitUntil