Compose & Espresso UI Testing Quiz

TESTING › UI

In Compose UI testing, what does a finder like onNodeWithText() query against?

Answer: The semantics tree used for accessibility and testing

Compose tests operate on the semantics tree, the same structure that powers accessibility, rather than the View hierarchy or rendered pixels.

Which rule should you use to test a Composable and also get a reference to the hosting Activity?

Answer: createAndroidComposeRule<MainActivity>() for the hosting Activity

createAndroidComposeRule<T>() launches the specified Activity and exposes it, whereas createComposeRule() hosts content without a particular Activity.

What is the correct order of the Espresso interaction pattern?

Answer: onView(matcher).perform(action).check(assertion)

Espresso uses onView(viewMatcher).perform(viewAction).check(viewAssertion): locate the view, act on it, then verify.

A node is in the semantics tree but scrolled off screen. Which assertion passes?

Answer: assertExists() passes but assertIsDisplayed() fails

assertExists() only checks presence in the semantics tree; assertIsDisplayed() additionally requires the node to be visible, which an off-screen node is not.

Why does Espresso usually not require manual Thread.sleep() calls between actions?

Answer: It waits for the message queue, AsyncTasks, and idling resources

Before each onView interaction, Espresso waits for the UI thread message queue, AsyncTasks, and registered idling resources to be idle, removing the need for manual sleeps.

You need to match a child Text inside a Button that Compose has merged into the parent's semantics. What do you do?

Answer: Pass useUnmergedTree = true to the finder

Merged semantics hide child nodes; querying with useUnmergedTree = true exposes the individual child so it can be matched.

Which Espresso API should you use to interact with an item in a Spinner or ListView?

Answer: onData() with a matcher on the adapter's backing data

AdapterView-backed widgets recycle off-screen items, so Espresso.onData() matches against the adapter's data and scrolls to it, unlike onView().

Which test runner must be declared as testInstrumentationRunner in build.gradle for AndroidX instrumented UI tests to run on a device?

Answer: androidx.test.runner.AndroidJUnitRunner

AndroidX instrumented tests use androidx.test.runner.AndroidJUnitRunner; the old android.test.InstrumentationTestRunner is deprecated and JUnit4's runner does not run on-device.

An Espresso test reliably fails because of an enabled system animation. What is the standard fix?

Answer: Disable the window, transition, and animator animation scales

Espresso cannot synchronize with animations, so the convention is to turn off the three system animation scales (or set testOptions.animationsDisabled true), not to add sleeps.

In Compose testing, what is the purpose of composeTestRule.waitUntil { ... }?

Answer: It polls a condition, driving the clock, until true or timeout

waitUntil repeatedly evaluates the supplied condition (driving the test clock) and returns when it becomes true, throwing if the timeout elapses first; it is the way to wait on conditions Compose's auto-sync cannot see.

You want a single Espresso assertion that no Toast or other view anywhere on screen displays a given error text. Which approach is correct?

Answer: onView(withText(errorText)).check(doesNotExist())

ViewAssertions.doesNotExist() passes only when the matcher resolves to no view in the hierarchy, which is how you assert absence; matches(isDisplayed()) would require the view to be present and visible.

Which dependency configuration correctly places the Compose UI test rule so it only ships in instrumented test builds?

Answer: androidTestImplementation("androidx.compose.ui:ui-test-junit4")

Compose UI tests run as instrumented tests, so ui-test-junit4 goes under androidTestImplementation; the debugImplementation slot is reserved for ui-test-manifest, not the test rule itself.

How do you reliably interact with an item inside a Compose LazyColumn whose item is not currently composed because it is scrolled off screen?

Answer: Use onNodeWithTag on the list, then performScrollToNode

Lazy lists only compose visible items, so off-screen nodes are absent from the semantics tree; you scroll the list node with performScrollToNode/performScrollToIndex to compose the target before acting on it.

What does setting composeTestRule.mainClock.autoAdvance = false enable you to do?

Answer: Step the clock via advanceTimeBy to inspect animation frames

Turning off autoAdvance hands you manual control of the test clock so you can step time with advanceTimeBy and inspect a UI mid-animation, rather than letting Compose jump straight to the idle end state.

Back to Compose & Espresso UI Testing