> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobster.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# XCTest targets

> Run your XCTest and Swift Testing targets with your checks, in one report.

`mobster test --xctest` also runs your project's own XCTest and Swift Testing targets, and puts unit tests, checks and screenshots in one report.

## Run your XCTest targets with your checks

```sh theme={"theme":"css-variables"}
mobster test --xctest
```

1. It builds your Xcode project once with `xcodebuild build-for-testing` into `.mobster/build`. `--scheme` and `--project` choose what to build (the only scheme, unless you name one), and `--test-plan` picks one of the scheme's test plans.
2. It runs the checks as usual, then `xcodebuild test-without-building` on a simulator Mobster leases for the run, with the result bundle at `.mobster/test-results/<suite-id>/xctest/tests.xcresult`.
3. It reads the `.xcresult` with `xcrun xcresulttool` (Xcode 16 or later) and merges it into the suite's reports.

`--only-testing Target/Class/test` runs only that target, class or test. Repeat it for more. With `mobster test pr --xctest`, the app the checks drive and the tests come from the same build, and the changed files choose the targets: a target runs when a changed file sits in a folder with its name, else every target runs. The pull request comment names the targets that ran and why.

```text theme={"theme":"css-variables"}
✗ failed  The paywall shows three plans with Annual at $39.99 a year on iPhone 17 Pro Max, iOS 26.4
    value id=plan_annual == "$39.99 / year": was "$39.99 / month"
✗ failed  YourAppTests: PlanTests.testAnnualPlanIsBilledYearly
    PlanTests.swift:16: XCTAssertEqual failed: ("month") is not equal to ("year")
XCTest: 3 of 4 passed, 1 failed in 1 target

Mobster checks: 2 passed, 1 failed, XCTest 1 failed of 4
```

## Read XCTest results

| file | what it holds |
| - | - |
| `index.html` | An XCTest section with a block per target, failures first. A target with failures opens. Each failed test shows its file and line and links its screenshots |
| `junit.xml` | One `<testsuite>` per target beside the devices' suites, one `<testcase classname="<class>">` per test, with `<failure type="xctest">` (its first line is `File.swift:14: message`) and `<skipped>` |
| `results.json` | `xctest`: `status`, `scheme`, `device`, `why` (per target), `summary` (`tests`, `passed`, `failed`, `skipped`) and `targets`, each with `cases` (`name`, `classname`, `status`, `durationMs`, `failures` with `message`, `file` and `line`, and `attachments`) |
| `xctest/attachments/` | Screenshots and files your tests attached, exported from the `.xcresult` |
| `--history` | Each test's last 20 results, with a flake score, as `xctest:Target/Class/test` |
| Pull request comment | One line per failed test with its file and line, and the targets that ran |
| Slack | Failed tests join the checks that didn't pass |

A failed test makes the exit code 1. If the build or the tests can't run (no test target in the scheme, no free simulator, only iPhones named), the XCTest section says why, the checks still count on their own, and the exit code is 3 unless a check failed.

Mobster runs your tests once, on one simulator, as your schemes and test plans define them. A test that fails once fails the run. The flake score in `--history` finds the unstable ones, and the quarantine file names checks, not tests.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.