AndroidComposeTestRule


Summary

Nested types

This class is deprecated. Do not instantiate this Statement, use AndroidComposeTestRule instead

Public constructors

<R : TestRule, A : ComponentActivity> AndroidComposeTestRule(
    activityRule: R,
    activityProvider: (R) -> A
)

Android specific implementation of ComposeContentTestRule, where compose content is hosted by an Activity.

android
@ExperimentalTestApi
<R : TestRule, A : ComponentActivity> AndroidComposeTestRule(
    activityRule: R,
    effectContext: CoroutineContext,
    activityProvider: (R) -> A
)

Android specific implementation of ComposeContentTestRule, where compose content is hosted by an Activity.

android

Public functions

open Statement
apply(base: Statement, description: Description)
android
open suspend Unit

Suspends until the UI is idle.

android
Unit

Cancels AndroidComposeUiTestEnvironment's current Recomposer and creates a new one.

android
open Unit

Disables accessibility checks.

android
open Unit

Enables accessibility checks that will be run before every action that is expected to change the UI.

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

Finds all semantics nodes that match the given condition.

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

Finds a semantics node that matches the given condition.

android
open Unit

Registers an IdlingResource in this test.

android
open 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.

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

Runs the given action on the UI thread.

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

Sets the given composable as a content of the current screen.

android
open Unit

Unregisters an IdlingResource from this test.

android
open Unit

Waits for the UI to become idle.

android
open Unit
waitUntil(timeoutMillis: Long, condition: () -> Boolean)

Blocks until the given condition is satisfied.

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

Blocks until the given condition is satisfied.

android
open Unit

Blocks until at least one node matches the given matcher.

android
open Unit

Blocks until no nodes match the given matcher.

android
open Unit

Blocks until exactly one node matches the given matcher.

android
open Unit
@ExperimentalTestApi
waitUntilNodeCount(
    matcher: SemanticsMatcher,
    count: Int,
    timeoutMillis: Long
)

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

android

Public properties

AccessibilityValidator?

The AccessibilityValidator that will be used to run Android accessibility checks before every action that is expected to change the UI.

android
A

Provides the current activity.

android
R
android
open Density

Current device screen's density.

android
open MainTestClock

Clock that drives frames and recompositions in compose tests.

android

Public constructors

AndroidComposeTestRule

<R : TestRule, A : ComponentActivity> AndroidComposeTestRule(
    activityRule: R,
    activityProvider: (R) -> A
)

Android specific implementation of ComposeContentTestRule, where compose content is hosted by an Activity.

The Activity is normally launched by the given activityRule before the test starts, but it is possible to pass a test rule that chooses to launch an Activity on a later time. The Activity is retrieved from the activityRule by means of the activityProvider, which can be thought of as a getter for the Activity on the activityRule. If you use an activityRule that launches an Activity on a later time, you should make sure that the Activity is launched by the time or while the activityProvider is called.

The AndroidComposeTestRule wraps around the given activityRule to make sure the Activity is launched after the AndroidComposeTestRule has completed all necessary steps to control and monitor the compose content.

Parameters
activityRule: R

Test rule to use to launch the Activity.

activityProvider: (R) -> A

Function to retrieve the Activity from the given activityRule.

AndroidComposeTestRule

@ExperimentalTestApi
<R : TestRule, A : ComponentActivity> AndroidComposeTestRule(
    activityRule: R,
    effectContext: CoroutineContext = EmptyCoroutineContext,
    activityProvider: (R) -> A
)

Android specific implementation of ComposeContentTestRule, where compose content is hosted by an Activity.

The Activity is normally launched by the given activityRule before the test starts, but it is possible to pass a test rule that chooses to launch an Activity on a later time. The Activity is retrieved from the activityRule by means of the activityProvider, which can be thought of as a getter for the Activity on the activityRule. If you use an activityRule that launches an Activity on a later time, you should make sure that the Activity is launched by the time or while the activityProvider is called.

The AndroidComposeTestRule wraps around the given activityRule to make sure the Activity is launched after the AndroidComposeTestRule has completed all necessary steps to control and monitor the compose content.

Parameters
activityRule: R

Test rule to use to launch the Activity.

effectContext: CoroutineContext = EmptyCoroutineContext

The CoroutineContext used to run the composition. The context for LaunchedEffects and rememberCoroutineScope will be derived from this context. If this context contains a TestDispatcher or TestCoroutineScheduler (in that order), it will be used for composition and the MainTestClock.

activityProvider: (R) -> A

Function to retrieve the Activity from the given activityRule.

Public functions

apply

open fun apply(base: Statement, description: Description): Statement

awaitIdle

open suspend fun awaitIdle(): Unit

Suspends until the UI is idle. Quiescence is reached when there are no more pending changes (e.g. pending recompositions or a pending draw call) and all IdlingResources are idle.

If auto advancement is enabled on the mainClock, this method will advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced which means that the Compose UI appears to be frozen. This is ideal for testing animations in a deterministic way. This method will always 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, Android's measure, layout and draw passes can still happen if required by the View system.

cancelAndRecreateRecomposer

fun cancelAndRecreateRecomposer(): Unit

Cancels AndroidComposeUiTestEnvironment's current Recomposer and creates a new one.

Recreates the CoroutineContext associated with Compose being cancelled. This happens when an app moves from a regular ("Full screen") view of the app to a "Pop up" view AND certain properties in the manifest's android:configChanges are set to prevent a full tear down of the app. This is a somewhat rare case (see AndroidComposeUiTestEnvironment for more details).

disableAccessibilityChecks

@RequiresApi(value = 34)
open fun disableAccessibilityChecks(): Unit

Disables accessibility checks.

This will set the accessibilityValidator back to null.

// Enable accessibility checks with your own AccessibilityValidator:
androidComposeTestRule.accessibilityValidator = AccessibilityValidator()
// By setting a non-null AccessibilityValidator, accessibility checks are enabled

// Configure the AccessibilityValidator:
androidComposeTestRule.accessibilityValidator!!.setThrowExceptionFor(
    AccessibilityCheckResultType.ERROR
)

enableAccessibilityChecks

@RequiresApi(value = 34)
open fun enableAccessibilityChecks(): Unit

Enables accessibility checks that will be run before every action that is expected to change the UI.

This will create and set an accessibilityValidator if there isn't one yet, or will do nothing if an accessibilityValidator is already set.

This requires API 34+ (Android U), and currently does not work on Robolectric.

import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollToIndex
import androidx.compose.ui.test.tryPerformAccessibilityChecks

// Enable accessibility checks with default configuration:
composeTestRule.enableAccessibilityChecks()

// Accessibility checks are run automatically when performing an action:
composeTestRule.onNodeWithText("Submit").performClick()

// You can also manually run accessibility checks:
composeTestRule.onRoot().tryPerformAccessibilityChecks()

// When disabling accessibility checks..
composeTestRule.disableAccessibilityChecks()

// .. they no longer run when performing an action:
composeTestRule.onNodeWithTag("list").performScrollToIndex(15)

onAllNodes

open fun onAllNodes(matcher: SemanticsMatcher, useUnmergedTree: Boolean): SemanticsNodeInteractionCollection

Finds all semantics nodes that match the given condition.

If you are working with elements that are not supposed to occur multiple times use onNode instead.

For usage patterns and semantics concepts see SemanticsNodeInteraction

Parameters
matcher: SemanticsMatcher

Matcher used for filtering.

useUnmergedTree: Boolean

If true, searches the unmerged semantics tree instead of the merged semantics tree. This allows you to search for individual nodes that would otherwise be part of a larger semantic unit, for example a text and an image forming a Button together.

See also
onNode

onNode

open fun onNode(matcher: SemanticsMatcher, useUnmergedTree: Boolean): SemanticsNodeInteraction

Finds a semantics node that matches the given condition.

Any subsequent operation on its result will expect exactly one element found (unless SemanticsNodeInteraction.assertDoesNotExist is used) and will throw an AssertionError if none or more than one element is found.

For usage patterns and semantics concepts see SemanticsNodeInteraction

Parameters
matcher: SemanticsMatcher

Matcher used for filtering

useUnmergedTree: Boolean

If true, searches the unmerged semantics tree instead of the merged semantics tree. This allows you to search for individual nodes that would otherwise be part of a larger semantic unit, for example a text and an image forming a Button together.

See also
onAllNodes

to work with multiple elements

registerIdlingResource

open fun registerIdlingResource(idlingResource: IdlingResource): Unit

Registers an IdlingResource in this test.

runOnIdle

open 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

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

Runs the given action on the UI thread.

This method is blocking until the action is complete.

setContent

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

Sets the given composable as a content of the current screen.

Use this in your tests to setup the UI content to be tested. This should be called exactly once per test.

Throws
kotlin.IllegalStateException

if called more than once per test.

unregisterIdlingResource

open fun unregisterIdlingResource(idlingResource: IdlingResource): Unit

Unregisters an IdlingResource from this test.

waitForIdle

open fun waitForIdle(): Unit

Waits for the UI to become idle. Quiescence is reached when there are no more pending changes (e.g. pending recompositions or a pending draw call) and all IdlingResources are idle.

If auto advancement is enabled on the mainClock, this method will advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced which means that the Compose UI appears to be frozen. This is ideal for testing animations in a deterministic way. This method will always 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, Android's measure, layout and draw passes can still happen if required by the View system.

waitUntil

open fun waitUntil(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 means that the Compose UI appears to be frozen. It is still valid to use this method in this way, if the condition will be satisfied by something not driven by our clock.

Compared to MainTestClock.advanceTimeUntil, waitUntil sleeps after every iteration to yield to other processes. 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
timeoutMillis: Long

The time after which this method throws an exception if the given condition is not satisfied. This observes wall clock time, not test clock 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).

waitUntil

open fun waitUntil(
    conditionDescription: String,
    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 means that the Compose UI appears to be frozen. It is still valid to use this method in this way, if the condition will be satisfied by something not driven by our clock.

Compared to MainTestClock.advanceTimeUntil, waitUntil sleeps after every iteration to yield to other processes. 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

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

waitUntilAtLeastOneExists

@ExperimentalTestApi
open fun 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
open fun 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
open fun 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
open fun 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

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

Public properties

accessibilityValidator

var accessibilityValidatorAccessibilityValidator?

The AccessibilityValidator that will be used to run Android accessibility checks before every action that is expected to change the UI.

If no validator is set (null), no checks will be performed. You can either supply your own validator directly, or have one configured for you with enableAccessibilityChecks.

The default value is null.

This requires API 34+ (Android U), and currently does not work on Robolectric.

// Enable accessibility checks with your own AccessibilityValidator:
androidComposeTestRule.accessibilityValidator = AccessibilityValidator()
// By setting a non-null AccessibilityValidator, accessibility checks are enabled

// Configure the AccessibilityValidator:
androidComposeTestRule.accessibilityValidator!!.setThrowExceptionFor(
    AccessibilityCheckResultType.ERROR
)

activity

val activity: A

Provides the current activity.

Avoid calling often as it can involve synchronization and can be slow.

activityRule

val activityRule: R

density

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

mainClock

open val mainClockMainTestClock

Clock that drives frames and recompositions in compose tests.