Deterministic sharding
An instrumentation run is split by class (`extra.class`), not blindly: every shard knows exactly which classes it runs. Aggregation spots tests executed twice and tests that never ran.
You push your APKs, Essaim splits the suite across several real devices and aggregates the JUnit results. Each device returns its verdict, its logs and its screenshots: the shard that fails is identified, not guessed.
No credit card to start. Secure payment through Stripe when you change plan.
Three shards in parallel, one single JUnit result.
An instrumentation run is split by class (`extra.class`), not blindly: every shard knows exactly which classes it runs. Aggregation spots tests executed twice and tests that never ran.
Essaim reads back the JUnit XML of every device, computes the totals and details the failures. The exit code is 0 when everything is green, 1 otherwise — in your CI, it blocks the merge.
The unit of account is the device minute. The cost of a run is computed before it starts, a minimum is reserved at creation time, and the real usage is settled at the end.
`POST /api/v1/runs`, the CLI `essaim run --app app.apk --test app-test.apk --devices pixel,samsung-a`, and a `run.completed` webhook signed with HMAC (X-Hangar-Signature).
Essaim stores no bytes: the upload is relayed to Hangar, and the customer only talks to Essaim through a signed URL of its own. Artifacts are served the same way.
Every device returns its JUnit XML. Essaim reads them back, adds them up, and spots what a naive sum lets through: a test run twice, a test that never ran.
| Shard | Device | Classes | Tests | Failures | Time |
|---|---|---|---|---|---|
| 1 | Redmi Note 13 | LoginTest, CartTest | 14 | 0 | 1 min 12 |
| 2 | SM-X110 (tablet) | SearchTest, ProfileTest | 14 | 0 | 58 s |
| 3 | next device | CheckoutTest, SettingsTest | 14 | 0 | 1 min 03 |
| Aggregated | 6 classes | 42 | 0 | 2 min 04 | |
run twice: 0 · never run: 0 · exit 0
The exit code is 0 when everything is green, 1 otherwise: in your CI, that is what blocks the merge.
A product that hides its limits wastes everybody's time. Here are ours, today.
No: the platform runs `am instrument <package>/<runner>` and Essaim does not read APKs. Without `test_package` the request is rejected with a 400.
Not today. On the platform side only a `capture` job records the screen: the `record_video` parameter of a `flow` job is accepted but ignored. The evidence delivered is `junit.xml`, `tests.json`, `instrument.log` and `logcat.txt` for instrumentation; `report.xml`, `steps.json`, `maestro.log` and the screenshots for flows.
At most 120 seconds. Beyond that the answer is a 202 and you have to poll the run — or listen to the `run.completed` webhook.
Not in phase 1. The selector targets a model or an Android version, but the multi-model matrix and the robot explorer (`monkey` without a package name) are not built: the platform requires the package, which Essaim cannot read from an APK.
Create an account, take a key, run your first test. It is free to start.