How does a Detox suite run with several workers on CI, and what must hold for the hotel-booking tests to run in parallel safely?
answer
- Jest maxWorkers, template sets 1
- one device per worker
- -Detox simulators, -read-only emulators
- --headless and --cleanup on CI
- no shared backend data between files
basics
~20 sDetox parallelism is Jest's maxWorkers: each worker allocates its own simulator or emulator, created or launched as needed. It is safe only when test files are order-independent and use separate backend data, and the runner has resources for every device.
solid answer
~40 sParallelism comes from Jest: `detox init` sets `maxWorkers: 1`, and on CI I raise it in the Jest config or with `detox test --maxWorkers 3`. Each worker allocates its own device through a locked registry — Detox creates `-Detox` simulators when none is free and launches extra emulator instances, which boot read-only with multiple workers. On the runner I add `--headless` and `--cleanup` so emulators have no window and are shut down at the end. Safety is about coupling: files must not depend on each other's sign-ins or bookings, each needs its own guest account and dates because devices are isolated but the backend is not, and the runner must have CPU and memory for every emulator.
code
javascript · 12 lines/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
rootDir: '..',
testMatch: ['<rootDir>/e2e/**/*.test.js'],
testTimeout: 120000,
maxWorkers: process.env.CI ? 3 : 1,
globalSetup: 'detox/runners/jest/globalSetup',
globalTeardown: 'detox/runners/jest/globalTeardown',
reporters: ['detox/runners/jest/reporter'],
testEnvironment: 'detox/runners/jest/testEnvironment',
verbose: true,
};go deeper
Recall that Detox parallelism comes from Jest's maxWorkers and that each worker needs its own device.
Explain how Detox allocates or creates devices per worker, what --headless and --cleanup do, and the device registry's role.
Make a suite parallel-safe: order independence, per-file backend data, keeping reinstall, and sizing workers to the runner.
Plan device capacity and sharding across machines against the pipeline's time budget and cost.
## Parallelism comes from Jest **Detox** runs test files in parallel through Jest's workers. `detox init` writes `maxWorkers: 1` into `e2e/jest.config.js`, because Jest's own default (CPU count minus one) would boot far too many devices on a laptop. On CI you raise it — in the Jest config (`maxWorkers: process.env.CI ? 2 : 1`) or per run with `detox test --maxWorkers 2`, which Detox forwards to Jest. ## One device per worker Each worker runs its current test file on a **device of its own**, allocated when the file's worker starts and released for reuse when it ends: - **iOS simulators** — Detox picks a free simulator matching the device query; if none is free it creates one, named after the device with a `-Detox` suffix. - **Android emulators** — Detox reuses a free running emulator of the AVD or launches another instance on a free port. With multiple workers, emulators always boot with `-read-only`, so several instances can share one AVD. - **Attached devices** — Detox can only share out what is plugged in; four workers need four matching devices. To keep workers from grabbing the same device, Detox keeps a lock-protected registry, `device.registry.json` (under `~/Library/Detox/` on macOS, `~/.local/share/Detox/` on Linux). ## CI-specific switches | Flag | Effect | Why on CI | |---|---|---| | `--maxWorkers N` | N files run at once, N devices | wall-clock time | | `--headless` / `-H` | Android emulator boots with `-no-window`; iOS runs without opening the Simulator app | no display on the runner | | `--cleanup` / `-u` | shuts down the simulators and emulators Detox used when the run ends | a reused runner starts clean next time | | `--record-logs failing` etc. | keeps artifacts for failed tests | evidence without huge uploads | The `headless` and shutdown behaviours can also be set in `.detoxrc.js` — `headless: true` on the device entry and `behavior.cleanup.shutdownDevice: true` — so the CI configuration carries them without long command lines. ## What must hold for parallel runs to be safe Parallelism turns hidden coupling between files into random failures. For the hotel-booking suite: 1. **No order dependence.** A file must not rely on another file having signed in, created a booking or seeded search history; files land on workers in no fixed order. 2. **Separate backend data.** Two files booking "Deluxe King, 12–14 June" with the same guest collide on the server even though each device is clean. Use a distinct account, hotel or date range per file. 3. **Device-level isolation.** Keep the default per-file reinstall; `--reuse` plus parallel workers makes leaked state random. 4. **Host resources.** Every emulator needs CPU and memory; on an under-sized runner, more workers make each device slower and raise timeouts. Measure the sweet spot rather than maximising workers. 5. **Readable logs.** With several workers Detox turns off its per-test progress lines by default (`testRunner.jest.reportSpecs`), so rely on artifacts and the Jest summary for failures. ## Keeping emulators fast enough - **Quick-boot snapshots.** The Detox Android environment guide strongly recommends saving a quick-boot snapshot for every test emulator, so parallel workers do not each pay a full cold boot. - **GPU mode.** On runners without a GPU, the device entry's `gpuMode` (for example `swiftshader_indirect`) selects software rendering explicitly. - **System dialogs.** Crash and "app not responding" dialogs make the UI unreachable for a whole batch of tests; the same guide suggests a helper app such as Test Butler, preinstalled through the device entry's `utilBinaryPaths`, to suppress them. ## Sharding across machines For larger suites, Jest's `--shard=1/3` splits files across CI machines, each with its own workers. Detox's retry mechanism drops `shard` on retries by default, so failed files re-run on the machine where they failed. ## A worked CI command ```bash detox test -c android.emu.release \ --maxWorkers 3 \ --headless \ --cleanup \ --record-logs failing \ --take-screenshots failing ``` On a runner with enough cores, this boots up to three headless emulators of the same AVD, runs files concurrently, keeps evidence for failures and shuts the emulators down at the end.
- Why not simply set maxWorkers to the runner's CPU count?Each worker drives a whole simulator or emulator, which is far heavier than a Jest unit-test worker. Past the point the runner can feed, extra devices slow each other down, raising timeouts and flakiness. Measure total time and failure rate at two, three and four workers and pick the knee of the curve.
- What do --headless and --cleanup do on an Android CI runner?`--headless` boots emulators with `-no-window`, which a display-less runner needs. `--cleanup` shuts the emulators Detox used down when the run ends, so a reused runner does not accumulate running emulators or leftover state for the next job.
saying these in an interview costs you the question
- Detox workers share one simulator to save resources.
- A clean device per worker also isolates backend data.
- More workers are always faster on any runner.
- Parallel runs keep test files in a fixed order.
- --cleanup deletes the test files' artifacts.