androidx.glance.appwidget.testing.unit

Interfaces

GlanceAppWidgetUnitTest

Provides methods to enable you to test your logic of building Glance composable content in the runGlanceAppWidgetUnitTest scope.

Objects

GlanceAppWidgetUnitTestDefaults

Provides default values for various properties used in the Glance appWidget unit tests.

Top-level functions summary

inline GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that runs a callback.

inline GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that sends a broadcast.

GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that sends a broadcast.

GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that sends a broadcast.

GlanceNodeMatcher<MappedNode>
hasSendBroadcastAction(
    intentAction: String,
    componentName: ComponentName?
)

Returns a matcher that matches if a node has a clickable set with action that sends a broadcast.

GlanceNodeMatcher<MappedNode>
hasStartActivityClickAction(
    intent: Intent,
    parameters: ActionParameters,
    activityOptions: Bundle?
)

Returns a matcher that matches if a node has a clickable set with action that starts an activity.

inline GlanceNodeMatcher<MappedNode>
<T : Service> hasStartServiceAction(isForegroundService: Boolean)

Returns a matcher that matches if a node has a clickable set with action that starts a service.

GlanceNodeMatcher<MappedNode>
hasStartServiceAction(intent: Intent, isForegroundService: Boolean)

Returns a matcher that matches if a node has a clickable set with action that starts a service.

GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node is checkable (e.g. radio button, switch, checkbox) and is checked.

GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a given node is an indeterminate circular progress indicator.

GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a given node is an indeterminate progress bar.

GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a given node is a linear progress indicator with given progress value.

GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node is checkable (e.g. radio button, switch, checkbox) but is not checked.

Unit

Sets up the test environment and runs the given unit test block.

Extension functions summary

inline GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that runs a callback.

inline GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that sends a broadcast.

GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that sends a broadcast.

GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that sends a broadcast.

GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that sends a broadcast.

GlanceNodeAssertion<MappedNodeGlanceMappedNode>
GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasStartActivityClickAction(
    intent: Intent,
    parameters: ActionParameters,
    activityOptions: Bundle?
)

Asserts that a given node has a clickable set with action that starts an activity.

inline GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that starts a service.

GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that starts a service.

GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that starts a service.

GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node is checkable and is checked.

GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node is checkable and is not checked.

Top-level functions

hasRunCallbackClickAction

inline fun <T : ActionCallback> hasRunCallbackClickAction(
    parameters: ActionParameters = actionParametersOf()
): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that runs a callback.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
<T : ActionCallback>

callback class that is expected to have been passed in the actionRunCallback method call

parameters: ActionParameters = actionParametersOf()

the parameters associated with the action that are expected to have been passed in the actionRunCallback method call

hasSendBroadcastAction

inline fun <T : BroadcastReceiver> hasSendBroadcastAction(): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that sends a broadcast.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
<T : BroadcastReceiver>

class of the broadcast receiver that is expected to have been passed in the actionSendBroadcast` method call.

hasSendBroadcastAction

fun hasSendBroadcastAction(componentName: ComponentName): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that sends a broadcast.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
componentName: ComponentName

ComponentName of the target broadcast receiver that is expected to have been passed in the actionSendBroadcast` method call.

hasSendBroadcastAction

fun hasSendBroadcastAction(intent: Intent): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that sends a broadcast.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
intent: Intent

the intent for sending broadcast that is expected to have been passed in the actionSendBroadcast method call. Note: intent is only matched using filterEquals.

hasSendBroadcastAction

fun hasSendBroadcastAction(
    intentAction: String,
    componentName: ComponentName? = null
): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that sends a broadcast.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
intentAction: String

the intent action of the broadcast receiver that is expected to have been passed in the actionSendBroadcast method call.

componentName: ComponentName? = null

optional ComponentName of the target broadcast receiver that is expected to have been passed in the actionSendBroadcast` method call.

hasStartActivityClickAction

fun hasStartActivityClickAction(
    intent: Intent,
    parameters: ActionParameters = actionParametersOf(),
    activityOptions: Bundle? = null
): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that starts an activity.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
intent: Intent

the intent for launching an activity that is expected to have been passed in the actionStartActivity method call. Note: Only matches if intents are same per filterEquals.

parameters: ActionParameters = actionParametersOf()

the parameters associated with the action that are expected to have been passed in the actionStartActivity method call

activityOptions: Bundle? = null

Additional options built from an android.app.ActivityOptions to apply to an activity start.

hasStartServiceAction

inline fun <T : Service> hasStartServiceAction(isForegroundService: Boolean = false): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that starts a service.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
<T : Service>

class of the service to launch that is expected to have been passed in the actionStartService method call.

isForegroundService: Boolean = false

if the service to launch is expected to have been set as foreground service in the actionStartService method call.

hasStartServiceAction

fun hasStartServiceAction(intent: Intent, isForegroundService: Boolean = false): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node has a clickable set with action that starts a service.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
intent: Intent

the intent for launching the service that is expected to have been passed in the actionStartService method call.

isForegroundService: Boolean = false

if the service to launch is expected to have been set as foreground service in the actionStartService method call.

fun isChecked(): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node is checkable (e.g. radio button, switch, checkbox) and is checked.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

isIndeterminateCircularProgressIndicator

fun isIndeterminateCircularProgressIndicator(): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a given node is an indeterminate circular progress indicator.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

isIndeterminateLinearProgressIndicator

fun isIndeterminateLinearProgressIndicator(): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a given node is an indeterminate progress bar.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

isLinearProgressIndicator

fun isLinearProgressIndicator(progress: Float): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a given node is a linear progress indicator with given progress value.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

Parameters
progress: Float

the expected value of the current progress

fun isNotChecked(): GlanceNodeMatcher<MappedNode>

Returns a matcher that matches if a node is checkable (e.g. radio button, switch, checkbox) but is not checked.

This can be passed in GlanceNodeAssertionsProvider.onNode and GlanceNodeAssertionsProvider.onAllNodes functions on assertion providers to filter out matching node(s) or in assertions to validate that node(s) satisfy the condition.

runGlanceAppWidgetUnitTest

fun runGlanceAppWidgetUnitTest(
    timeout: Duration = DEFAULT_TIMEOUT,
    block: GlanceAppWidgetUnitTest.() -> Unit
): Unit

Sets up the test environment and runs the given unit test block. Use the methods on GlanceAppWidgetUnitTest in the test to provide Glance composable content, find Glance elements and make assertions on them.

Test your individual Glance composable functions in isolation to verify that your logic outputs right elements. For example: if input data is 'x', an image 'y' was outputted. In sample below, the test class has a separate test for the header and the status row.

Tests can be run on JVM as these don't involve rendering the UI. If your logic depends on Context or other android APIs, tests can be run on Android unit testing frameworks such as Robolectric.

Note: Keeping a reference to the GlanceAppWidgetUnitTest outside of this function is an error.

import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.glance.GlanceModifier
import androidx.glance.LocalSize
import androidx.glance.appwidget.testing.unit.runGlanceAppWidgetUnitTest
import androidx.glance.layout.Column
import androidx.glance.layout.Row
import androidx.glance.layout.Spacer
import androidx.glance.layout.fillMaxSize
import androidx.glance.layout.width
import androidx.glance.semantics.semantics
import androidx.glance.semantics.testTag
import androidx.glance.testing.unit.hasTestTag
import androidx.glance.testing.unit.hasText
import androidx.glance.text.Text

class TestSample {
    @Test
    fun statusContent_statusFalse_outputsPending() = runGlanceAppWidgetUnitTest {
        provideComposable {
            StatusRow(
                status = false
            )
        }

        onNode(hasTestTag("status-text"))
            .assert(hasText("Pending"))
    }

    @Test
    fun statusContent_statusTrue_outputsFinished() = runGlanceAppWidgetUnitTest {
        provideComposable {
            StatusRow(
                status = true
            )
        }

        onNode(hasTestTag("status-text"))
            .assert(hasText("Finished"))
    }

    @Test
    fun header_smallSize_showsShortHeaderText() = runGlanceAppWidgetUnitTest {
        setAppWidgetSize(DpSize(width = 50.dp, height = 100.dp))

        provideComposable {
            StatusRow(
                status = false
            )
        }

        onNode(hasTestTag("header-text"))
            .assert(hasText("MyApp"))
    }

    @Test
    fun header_largeSize_showsLongHeaderText() = runGlanceAppWidgetUnitTest {
        setAppWidgetSize(DpSize(width = 150.dp, height = 100.dp))

        provideComposable {
            StatusRow(
                status = false
            )
        }

        onNode(hasTestTag("header-text"))
            .assert(hasText("MyApp (Last order)"))
    }

    @Composable
    fun WidgetContent(status: Boolean) {
        Column {
            Header()
            Spacer()
            StatusRow(status)
        }
    }

    @Composable
    fun Header() {
        val width = LocalSize.current.width
        Row(modifier = GlanceModifier.fillMaxSize()) {
            Text(
                text = if (width > 50.dp) {
                    "MyApp (Last order)"
                } else {
                    "MyApp"
                },
                modifier = GlanceModifier.semantics { testTag = "header-text" }
            )
        }
    }

    @Composable
    fun StatusRow(status: Boolean) {
        Row(modifier = GlanceModifier.fillMaxSize()) {
            Text(
                text = "Status",
            )
            Spacer(modifier = GlanceModifier.width(10.dp))
            Text(
                text = if (status) {
                    "Pending"
                } else {
                    "Finished"
                },
                modifier = GlanceModifier.semantics { testTag = "status-text" }
            )
        }
    }
}
Parameters
timeout: Duration = DEFAULT_TIMEOUT

test time out; defaults to 10s

block: GlanceAppWidgetUnitTest.() -> Unit

The test block that involves calling methods in GlanceAppWidgetUnitTest

Extension functions

assertHasRunCallbackClickAction

inline fun <T : ActionCallback> GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasRunCallbackClickAction(
    parameters: ActionParameters = actionParametersOf()
): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that runs a callback.

Parameters
<T : ActionCallback>

action callback that is expected to have been passed in the actionRunCallback method call

parameters: ActionParameters = actionParametersOf()

the parameters associated with the action that are expected to have been passed in the actionRunCallback method call

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertHasSendBroadcastClickAction

inline fun <T : BroadcastReceiver> GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasSendBroadcastClickAction(

): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that sends a broadcast.

Parameters
<T : BroadcastReceiver>

class of the broadcast receiver that is expected to have been passed in the actionSendBroadcast method call.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertHasSendBroadcastClickAction

fun GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasSendBroadcastClickAction(
    componentName: ComponentName
): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that sends a broadcast.

Parameters
componentName: ComponentName

ComponentName of the target broadcast receiver that is expected to have been passed in the actionSendBroadcast method call.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertHasSendBroadcastClickAction

fun GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasSendBroadcastClickAction(
    intent: Intent
): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that sends a broadcast.

Parameters
intent: Intent

the intent for sending broadcast that is expected to have been passed in the actionSendBroadcast method call. Note: intent is only matched using filterEquals.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertHasSendBroadcastClickAction

fun GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasSendBroadcastClickAction(
    intentAction: String,
    componentName: ComponentName? = null
): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that sends a broadcast.

Parameters
intentAction: String

the intent action of the broadcast receiver that is expected to have been passed in the actionSendBroadcast method call.

componentName: ComponentName? = null

optional ComponentName of the target broadcast receiver that is expected to have been passed in the actionSendBroadcast method call.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertHasStartActivityClickAction

fun GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasStartActivityClickAction(
    intent: Intent,
    parameters: ActionParameters = actionParametersOf(),
    activityOptions: Bundle? = null
): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that starts an activity.

Parameters
intent: Intent

the intent for launching an activity that is expected to have been passed in the actionStartActivity method call

parameters: ActionParameters = actionParametersOf()

the parameters associated with the action that are expected to have been passed in the actionStartActivity method call

activityOptions: Bundle? = null

Additional options built from an android.app.ActivityOptions to apply to an activity start.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertHasStartServiceClickAction

inline fun <T : Service> GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasStartServiceClickAction(
    isForegroundService: Boolean = false
): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that starts a service.

Parameters
<T : Service>

class of the service to launch that is expected to have been passed in the actionStartService method call.

isForegroundService: Boolean = false

if the service to launch is expected to have been set as foreground service in the actionStartService method call.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertHasStartServiceClickAction

fun GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasStartServiceClickAction(
    componentName: ComponentName,
    isForegroundService: Boolean = false
): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that starts a service.

Parameters
componentName: ComponentName

component of the service to launch that is expected to have been passed in the actionStartService method call.

isForegroundService: Boolean = false

if the service to launch is expected to have been set as foreground service in the actionStartService method call.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertHasStartServiceClickAction

fun GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertHasStartServiceClickAction(
    intent: Intent,
    isForegroundService: Boolean = false
): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node has a clickable set with action that starts a service.

Parameters
intent: Intent

the intent for launching the service that is expected to have been passed in the actionStartService method call.

isForegroundService: Boolean = false

if the service to launch is expected to have been set as foreground service in the actionStartService method call.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertIsChecked

fun GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertIsChecked(): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node is checkable and is checked.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.

assertIsNotChecked

fun GlanceNodeAssertion<MappedNodeGlanceMappedNode>.assertIsNotChecked(): GlanceNodeAssertion<MappedNodeGlanceMappedNode>

Asserts that a given node is checkable and is not checked.

Throws
kotlin.AssertionError

if the matcher does not match or the node can no longer be found.