skip to content

For React Native end-to-end tests, how do Detox, Maestro and Appium differ in how they drive the app and wait for it?

level: middleimportance: should knowfreq 46%

answer

  1. gray box versus black box
  2. Detox waits for the app to go idle
  3. Maestro: YAML flows, built-in waits
  4. Appium: WebDriver, any client language
  5. Detox mocks through Metro, not jest.mock

basics

~20 s

Detox is gray-box: a native client inside the app build lets it wait until React Native, network and animations are idle. Maestro and Appium drive the app black-box from outside, Maestro from YAML flows and Appium through the WebDriver protocol.

solid answer

~40 s

Detox is built for React Native and is **gray-box**: a native Detox client runs inside the tested app and synchronises with it, waiting for in-flight network requests, animations, short timers and pending work on the JavaScript and native-module threads before each action. Tests are JavaScript on Jest, and mocking happens through Metro, not `jest.mock`. **Maestro** is black-box: flows are YAML files run against an installed app, and it copes with timing through built-in waiting and retries rather than knowledge of the app's internals. **Appium** is black-box over the **WebDriver** protocol, with clients in many languages and platform drivers underneath, which suits teams that already run WebDriver suites or test native and React Native apps side by side. Detox trades setup work for determinism; the other two trade some determinism for lower coupling.

go deeper

for a junior

Recall the three names and the headline difference: Detox waits for the app to be idle from inside, Maestro and Appium drive it from outside.

for a middle

Explain gray-box synchronisation, what Detox waits for, how each tool is authored, and why Detox mocks through Metro rather than jest.mock.

for a senior

Anticipate each tool's failure modes, such as Detox idle timeouts from endless loaders and explicit-wait flakiness in black-box suites, and design around them.

for a principal

Choose the E2E tool by team skills, existing infrastructure and flakiness tolerance, and keep the device layer small whichever tool wins.

## Two ways to know when the app is ready Every end-to-end (E2E) tool for mobile must answer one question before each step: **is the app ready for the next tap?** The three tools interviewers compare for React Native answer it differently. - A **black-box** tool sees the app only from outside, like a user. It must guess readiness by polling the screen, waiting or retrying. - A **gray-box** tool has a component inside the app that can observe its internal state and report when it is idle. ## Detox: gray box, synchronised with React Native Detox's own documentation describes it as gray-box and lists what it synchronises with automatically: - in-flight **network requests**; - pending work on the **native main thread** and **UI layout**, including React Native's layout work where Yoga runs; - **timers**: JavaScript `setTimeout` is monitored, while `setInterval` is ignored by default; - **animations**, with special support for React Native's `Animated` and Reanimated; - pending operations on the **React Native JavaScript thread** and the **native-modules thread**. Detox proceeds to the next action only after the app is idle, which removes most of the `sleep` calls black-box suites need. Architecturally, the test code runs in **Node.js** on a runner such as **Jest**, a native Detox client is built into the tested app, and the two talk through a small WebSocket server. Detox avoids WebDriver on purpose and evaluates expectations inside the app. Consequences worth knowing: 1. **Setup cost.** The app needs a Detox-aware build for each platform, and device types such as iOS simulators, Android emulators and attached Android devices are configured per project. 2. **Mocking** is done through **Metro**, for example by serving `.mock.js` files instead of the real ones; Detox's guide states that `jest.mock` does not work because the app runs in its own process. 3. **Strictness.** An endless loader or a polling timer keeps the app busy, so Detox times out waiting for idle. The docs treat this as a feature that exposes leaks, with escape hatches such as URL blacklists and manual synchronisation. ## Maestro: black box with flows in YAML Maestro drives an installed app from outside. Tests are **flows written in YAML** that describe steps such as launching the app, tapping on visible text and asserting what is on screen. It needs no test client compiled into the app, and it handles timing with built-in waiting and retries instead of reading the app's internal state. That makes flows quick to write and readable by people who do not write JavaScript, at the cost of not knowing exactly when React Native's work is finished. ## Appium: black box over WebDriver Appium exposes mobile automation through the **WebDriver** protocol. Test code can be written in any language with a WebDriver client, and platform-specific drivers underneath talk to the operating system's automation frameworks. Because it treats the app as a black box, it does not care whether the app is React Native, native or hybrid, which suits organisations with an existing WebDriver practice or a mixed app portfolio. The trade-off is more explicit waiting in tests and slower command round-trips. ## Side by side | Aspect | Detox | Maestro | Appium | |---|---|---|---| | Box | Gray | Black | Black | | Knows when React Native is idle | Yes, by synchronisation | No, waits and retries | No, explicit waits | | Test language | JavaScript or TypeScript on Jest | YAML flows | Any WebDriver client language | | Changes to the app build | Detox client built in | None | None for the app itself | | Mocking app modules | Metro-level substitutions | Outside the app (backend, config) | Outside the app | | Fits best | React Native teams wanting determinism | Fast authoring, mixed-skill teams | Existing WebDriver suites, mixed stacks | ## Choosing There is no universal winner. A React Native team whose developers write the tests and want the fewest timing flakes usually leans to Detox and accepts the build integration. A team that wants flows authored quickly, or by QA without JavaScript, looks at Maestro. An organisation already invested in WebDriver infrastructure or testing several app stacks with one toolset looks at Appium. Whatever the choice, the E2E layer should stay small and cover vital flows, because every tool pays for a real build and a real device or simulator.

  • A Detox test times out waiting for the app to become idle on a screen with a spinning loader; what is happening?
    Detox synchronises with animations and waits for the app to be idle before acting. An endless loader, or a short `setTimeout` polling loop, keeps the app permanently busy, so the wait times out. Fix the leak, hide the loader in tests through a Metro-level mock, or as a last resort switch that part of the test to manual synchronisation.
  • Why doesn't jest.mock work for mocking a module in a Detox test?
    Detox's test code runs in Node, but the app runs in its own process on the simulator or device with a bundle built by Metro. `jest.mock` only replaces modules inside the Node test process. To substitute app modules, configure Metro to serve mock files, for example through an extra source extension such as `.mock.js`.

saying these in an interview costs you the question

  • Detox drives the app through the WebDriver protocol
  • Maestro needs a test client compiled into the React Native app
  • Appium can see when the React Native JavaScript thread is idle
  • jest.mock in a Detox test replaces modules inside the running app
  • Gray-box synchronisation removes every source of E2E flakiness