{% setvar book_path %}/reference/androidx/_book.yaml{% endsetvar %} {% include "_shared/_reference-head-tags.html" %}

ComposeUiTest

@ExperimentalTestApi
public sealed interface ComposeUiTest extends SemanticsNodeInteractionsProvider

Known direct subclasses
AndroidComposeUiTest

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


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 methods

abstract void

Suspends until compose is idle.

abstract @NonNull Density

Current device screen's density.

abstract @NonNull MainTestClock

Clock that drives frames and recompositions in compose tests.

abstract void

Registers an IdlingResource in this test.

abstract @NonNull T
<T extends Object> runOnIdle(@NonNull Function0<@NonNull T> action)

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

abstract @NonNull T
<T extends Object> runOnUiThread(@NonNull Function0<@NonNull T> action)

Runs the given action on the UI thread.

abstract void
setContent(@Composable @NonNull Function0<Unit> composable)

Sets the given composable as the content to be tested.

abstract void

Unregisters an IdlingResource from this test.

abstract void

Waits for compose to be idle.

abstract void
waitUntil(
    long timeoutMillis,
    @NonNull Function0<@NonNull Boolean> condition
)

Blocks until the given condition is satisfied.

Extension functions

default final void
@ExperimentalTestApi
ComposeUiTestKt.waitUntilAtLeastOneExists(
    @NonNull ComposeUiTest receiver,
    @NonNull SemanticsMatcher matcher,
    long timeoutMillis
)

Blocks until at least one node matches the given matcher.

default final void
@ExperimentalTestApi
ComposeUiTestKt.waitUntilDoesNotExist(
    @NonNull ComposeUiTest receiver,
    @NonNull SemanticsMatcher matcher,
    long timeoutMillis
)

Blocks until no nodes match the given matcher.

default final void
@ExperimentalTestApi
ComposeUiTestKt.waitUntilExactlyOneExists(
    @NonNull ComposeUiTest receiver,
    @NonNull SemanticsMatcher matcher,
    long timeoutMillis
)

Blocks until exactly one node matches the given matcher.

default final void
@ExperimentalTestApi
ComposeUiTestKt.waitUntilNodeCount(
    @NonNull ComposeUiTest receiver,
    @NonNull SemanticsMatcher matcher,
    int count,
    long timeoutMillis
)

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

Inherited methods

From androidx.compose.ui.test.SemanticsNodeInteractionsProvider
abstract @NonNull SemanticsNodeInteractionCollection
onAllNodes(@NonNull SemanticsMatcher matcher, boolean useUnmergedTree)

Finds all semantics nodes that match the given condition.

abstract @NonNull SemanticsNodeInteractionCollection
onAllNodes(@NonNull SemanticsMatcher matcher, boolean useUnmergedTree)

Finds all semantics nodes that match the given condition.

abstract @NonNull SemanticsNodeInteraction
onNode(@NonNull SemanticsMatcher matcher, boolean useUnmergedTree)

Finds a semantics node that matches the given condition.

abstract @NonNull SemanticsNodeInteraction
onNode(@NonNull SemanticsMatcher matcher, boolean useUnmergedTree)

Finds a semantics node that matches the given condition.

Public methods

awaitIdle

abstract void awaitIdle()

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.

getDensity

abstract @NonNull Density getDensity()

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.

getMainClock

abstract @NonNull MainTestClock getMainClock()

Clock that drives frames and recompositions in compose tests.

registerIdlingResource

abstract void registerIdlingResource(@NonNull IdlingResource idlingResource)

Registers an IdlingResource in this test.

runOnIdle

abstract @NonNull T <T extends Object> runOnIdle(@NonNull Function0<@NonNull T> action)

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

abstract @NonNull T <T extends Object> runOnUiThread(@NonNull Function0<@NonNull T> action)

Runs the given action on the UI thread.

This method blocks until the action is complete.

setContent

abstract void setContent(@Composable @NonNull Function0<Unit> composable)

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

abstract void unregisterIdlingResource(@NonNull IdlingResource idlingResource)

Unregisters an IdlingResource from this test.

waitForIdle

abstract void waitForIdle()

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

abstract void waitUntil(
    long timeoutMillis,
    @NonNull Function0<@NonNull Boolean> condition
)

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
long timeoutMillis

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

@NonNull Function0<@NonNull Boolean> condition

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).

Extension functions

ComposeUiTestKt.waitUntilAtLeastOneExists

@ExperimentalTestApi
default final void ComposeUiTestKt.waitUntilAtLeastOneExists(
    @NonNull ComposeUiTest receiver,
    @NonNull SemanticsMatcher matcher,
    long timeoutMillis
)

Blocks until at least one node matches the given matcher.

Parameters
@NonNull SemanticsMatcher matcher

The matcher that will be used to filter nodes.

long timeoutMillis

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

ComposeUiTestKt.waitUntilDoesNotExist

@ExperimentalTestApi
default final void ComposeUiTestKt.waitUntilDoesNotExist(
    @NonNull ComposeUiTest receiver,
    @NonNull SemanticsMatcher matcher,
    long timeoutMillis
)

Blocks until no nodes match the given matcher.

Parameters
@NonNull SemanticsMatcher matcher

The matcher that will be used to filter nodes.

long timeoutMillis

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

ComposeUiTestKt.waitUntilExactlyOneExists

@ExperimentalTestApi
default final void ComposeUiTestKt.waitUntilExactlyOneExists(
    @NonNull ComposeUiTest receiver,
    @NonNull SemanticsMatcher matcher,
    long timeoutMillis
)

Blocks until exactly one node matches the given matcher.

Parameters
@NonNull SemanticsMatcher matcher

The matcher that will be used to filter nodes.

long timeoutMillis

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

ComposeUiTestKt.waitUntilNodeCount

@ExperimentalTestApi
default final void ComposeUiTestKt.waitUntilNodeCount(
    @NonNull ComposeUiTest receiver,
    @NonNull SemanticsMatcher matcher,
    int count,
    long timeoutMillis
)

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

Parameters
@NonNull SemanticsMatcher matcher

The matcher that will be used to filter nodes.

int count

The number of nodes that are expected to

long timeoutMillis

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