Espresso 101
May 5, 2026 · View on GitHub
Espresso is Google's first-party Android UI test framework. Tests run inside the app process under the JVM, which means they're fast and reliable but Android-only.
For FrontRow we use Espresso to demonstrate native Android testing against a React Native UI. testIDs in src/testIds.ts are exposed as Android resource-id values, so Espresso matches them with withResourceName(...).
Setup
You need:
- Android Studio (or just the SDK + Gradle)
- An emulator or device connected via
adb - FrontRow built once with
npx expo run:android
Copy the test templates into the standard instrumentation folder:
mkdir -p android/app/src/androidTest/java/app/frontrow/qa
cp tests/espresso/*.kt android/app/src/androidTest/java/app/frontrow/qa/
Run the smoke test
cd android
./gradlew :app:connectedAndroidTest
Gradle builds a test APK, installs it alongside the FrontRow APK on the connected device, and runs the test class.
Anatomy of a test
@RunWith(AndroidJUnit4::class)
class SmokeEspressoTest {
@get:Rule
val activityRule = ActivityScenarioRule(ReactActivity::class.java)
@Test
fun appLaunches_eventsTabIsVisible() {
onView(withResourceName("screen.events")).check(matches(isDisplayed()))
}
}
Key points:
ActivityScenarioRulelaunches the React Native activity. FrontRow's main activity extendsReactActivity.withResourceName("screen.events")matches against the React Native View'snativeID, which RN sets from thetestIDprop.- Espresso has its own assertion DSL:
matches(isDisplayed()),matches(withText("...")), etc.
Common matchers
withResourceName("eventDetail.buyButton") // testID
withText("Buy") // visible text
withContentDescription("Buy ticket") // accessibilityLabel
allOf(withResourceName("..."), isDisplayed()) // composing
Driving the app
Espresso has a fluent API: find a view, perform an action.
onView(withResourceName("eventDetail.buyButton")).perform(click())
onView(withResourceName("login.emailInput")).perform(typeText("demo@frontrow.app"))
Where Espresso shines vs. Maestro/Appium
- It's 5–10× faster than Appium because there's no WebDriver protocol.
- It runs in-process, so you can read the app's internal state in tests if you need to.
Where Espresso falls short
- Android only.
- You need a working Android Studio toolchain.
- Tests share a JVM with the app, so a crash in the app crashes the test run.
Where to look next
- Google's Espresso cheat sheet.
tests/espresso/SmokeEspressoTest.ktas a starting point.- For multi-step flows, look at Espresso's
IdlingResourceto wait on async work.