TestFailureHandler
-
Cmn
fun interface TestFailureHandler
Handles Compose UI test failures for custom diagnostics or artifact processing.
Implementations are registered in a TestFailurePolicy within a ComposeUiTestConfig and execute in the order provided. If a handler throws an exception, the framework catches and attaches it as a suppressed exception to FailureContext.error, ensuring the original test failure is never masked.
Handlers execute synchronously on the test thread in a post-mortem state where the Compose hierarchy, coroutine scopes, and UI registries have already been torn down. As a result, interactive testing APIs like ComposeUiTest.waitForIdle or onNodeWithTag cannot be called within a handler.
Because handlers execute after the test timeout has elapsed, blocking calls such as file IO or network operations can delay or stall the test runner indefinitely. Handlers that perform heavy IO should enforce their own tight timeouts or dispatch work to background threads.
import androidx.compose.ui.test.ComposeUiTestConfig import androidx.compose.ui.test.FailureArtifact import androidx.compose.ui.test.TestFailureHandler import androidx.compose.ui.test.TestFailurePolicy import androidx.compose.ui.test.TestFailurePolicy.CaptureMode import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.v2.runComposeUiTest import androidx.test.platform.io.PlatformTestStorageRegistry val customFailureHandler = TestFailureHandler { context -> val storage = PlatformTestStorageRegistry.getInstance() context.artifacts.forEach { artifact -> when (artifact.type) { FailureArtifact.Type.Screenshot -> { // Example: Read the screenshot bytes to upload to a custom dashboard // val inputStream = storage.openInputFile(artifact.fileName) } FailureArtifact.Type.UiHierarchy -> { // Example: Get the URI to share or process further // val uri = storage.getOutputFileUri(artifact.fileName) } } } } val testConfig = ComposeUiTestConfig( failurePolicy = TestFailurePolicy( screenshotCaptureMode = CaptureMode.Enabled, uiHierarchyCaptureMode = CaptureMode.Enabled, failureHandlers = listOf(customFailureHandler), ) ) runComposeUiTest(config = testConfig) { setContent { /* Your Compose UI here */ } // If this assertion fails, the framework will: // 1. Take a screenshot // 2. Dump the UI hierarchy // 3. Call customFailureHandler.onTestFailed onNodeWithTag("non_existent_button").assertExists() }
| See also | |
|---|---|
TestFailurePolicy |
|
FailureContext |
Summary
Public functions |
||
|---|---|---|
Unit |
onTestFailed(context: FailureContext)Invoked synchronously on the test thread when a Compose UI test fails. |
Cmn
|
Public functions
onTestFailed
fun onTestFailed(context: FailureContext): Unit
Invoked synchronously on the test thread when a Compose UI test fails.
| Parameters | |
|---|---|
context: FailureContext |
The |