XCUITest alternatives: keep XCUITest, add an agent
Mobster checks your iOS app from outside the Xcode project: plain-English checks your coding agent runs, with pass or fail from the accessibility tree.
Facts about XCUITest read on , from the sources at the end.
Pick Mobster if a coding agent is writing your SwiftUI screens: it checks each one from outside your Xcode project, with no test target and no test code, and returns pass or fail from the same accessibility tree XCUITest reads.
We make Mobster, and every XCUITest fact here comes from Apple’s own documentation, listed under Sources.
| Feature | Mobster | XCUITest |
|---|---|---|
| Test target | ✓ None: Mobster checks the .app from outside your project | A UI test target in your Xcode project |
| A check is written in | ✓ Plain-English steps plus what must be true, in YAML | Swift or Objective-C |
| Your coding agent | ✓ Drives the app over MCP and gets pass or fail, mid-task | Writes test code, then runs xcodebuild test |
| Who performs the steps | ✓ Nobody (launch-only), your coding agent, or Mobster’s Smart agent | Your test code |
| Proof for each verdict | ✓ Frames, an overlay of each asserted element, a one-file HTML report, up to 5 near misses on a failure | An .xcresult bundle |
| Simulators | ✓ Mobster’s own, headless; the app reset before each run | The simulators you manage in Xcode |
| Keep a run as a check | ✓ --save, or save_check from your agent | Xcode’s record button writes queries as you tap |
| A real iPhone | ✓ Over USB, an app you installed, its data never cleared | ✓ Devices with Xcode |
| Price | ✓ CLI free (MIT); Mac app $34.99 one time | Free with Xcode |
Four reasons to pick Mobster
1. Your coding agent checks the screen it wrote
An agent that changes a SwiftUI view needs to know the view works before it says so. With Mobster it builds for the simulator, calls verify_start with the steps in plain English and what must be true, drives the app with screen, tap, type_text and swipe, and calls verify_finish. The expectations are fixed before the agent touches the app, so it can’t bend them to fit what it sees. There’s no test target to add and no test code to compile. Paste this into CLAUDE.md or AGENTS.md and the agent does it after every UI change:
## Verifying UI changesAfter you change a screen in this iOS app, verify it before you say it works.1. Build for the simulator: xcodebuild -scheme <Scheme> -destination 'generic/platform=iOS Simulator' -derivedDataPath .mobster/build CODE_SIGNING_ALLOWED=NO build2. Call mobster's verify_start with app_path set to the absolute path of .mobster/build/Build/Products/Debug-iphonesimulator/<App>.app, the steps in plain English, and expect: what must be true when the steps are done.3. Drive with screen, tap, type_text and swipe, then call verify_finish.4. If the verdict is failed, fix the code and verify again. Report the verdict and the report path.2. A check is a small file anyone can read
Daybreak, the sample app in Mobster’s repository, ships this one as .mobster/checks/paywall.yaml:
# Launch-only: no steps and no model calls. Mobster installs Daybreak, opens the paywall by# deep link, and checks it against the accessibility tree.# mobster verify --check .mobster/checks/paywall.yamlversion: 1name: The paywall shows three plans with Annual at $39.99 a yearapp: bundle: dev.mobster.daybreak path: .build/Build/Products/Debug-iphonesimulator/Daybreak.applaunch: url: daybreak://paywallexpect: - text: Choose your plan - count: { id: /^plan_/ } equals: 3 - value: { id: plan_annual } equals: $39.99 / year - visible: { label: Restore Purchases, role: button } - no_text: Loadingmobster verify --check runs it, and the exit code is the verdict. Any run becomes a file like this with --save, or with save_check from your agent.
3. Proof a person can read
Every run writes frames, an overlay that outlines every element Mobster read and each asserted element in green or red, result.json, and a one-file HTML report with no external requests. When text isn’t found, the assertion line lists up to 5 near misses from the screen, so the agent fixes the right code and you can trust the verdict without rerunning it.
4. Simulators handled for you, and your iPhone too
Mobster creates its own simulators, boots them headless, builds WebDriverAgent once per Xcode version and resets the app before each run. It never opens Simulator.app and never touches your own simulators. On a warm simulator, Daybreak’s five-assertion paywall check took 6.8 s and 8.6 s (n = 2, 28 September 2026, an M5 Max with Xcode 26.4 and the iOS 26.4 simulator). On your USB iPhone, with Developer Mode on, mobster verify --device checks an app you already installed there, without clearing its data.
When XCUITest fits
Keep XCUITest for the regression suite that compiles with your app and runs in any CI or Xcode Cloud. Give the controls you check an accessibility identifier, such as .accessibilityIdentifier("plan_annual"), and XCUITest queries and Mobster’s id selector both use it.
Try Mobster on your app
The CLI is free:
curl -fsSL https://mobster.dev/install.sh | sh
mobster sim doctor --fix
xcodebuild -scheme <Scheme> -destination 'generic/platform=iOS Simulator' \
-derivedDataPath .mobster/build CODE_SIGNING_ALLOWED=NO build
mobster verify --app .mobster/build/Build/Products/Debug-iphonesimulator/<App>.app \
--text "Welcome" --save first-checkReplace "Welcome" with text your first screen shows. --save first-check keeps the check as .mobster/checks/first-check.yaml, ready to commit. Mobster for Mac adds guided setup for your iPhone, a live view and history, for $34.99 one time.
Getting started with verify walks through the rest, and Maestro vs XCUITest vs Mobster adds Maestro to the comparison.
Questions
Is Mobster a replacement for XCUITest?
For your coding agent's checks, yes: it checks a screen with no test code and no test target. For a regression suite in CI and Xcode Cloud, keep XCUITest, and let your agent check each screen with Mobster while it works.
Does Mobster need a UI test target?
No. It installs the .app you build for the iOS Simulator with CODE_SIGNING_ALLOWED=NO, and reads the app's accessibility tree through WebDriverAgent, an XCTest runner of its own.
Do accessibility identifiers work in both?
Yes. Mobster's id selector matches the accessibility identifier you set with .accessibilityIdentifier in SwiftUI, the same identifier an XCUITest query uses. One identifier serves both.
Sources
Every fact about the other tool comes from its own site, docs or repository, read on 8 October 2026. Reviewed by Andy Guo on . Corrections are welcome at the GitHub repo.
Mobster isn’t affiliated with or endorsed by Apple.
Related posts
6 min read
How to test an iOS app with an AI agent
Let a model drive your iOS app and never let it judge. Mobster decides pass or fail from accessibility tree assertions on one settled screen, with proof.
4 min read
Maestro vs XCUITest vs Mobster: when to use which
XCUITest, Maestro and Mobster all check iOS screens. If a coding agent writes yours, Mobster is built for it: plain-English checks, verdicts from assertions.