QA Testing (iOS)
Use xcodebuild + Xcode Simulator (simctl) to build, run, and stabilize iOS tests.
Primary docs: XCTest, Swift Testing, simctl, Xcode testing
Inputs to Confirm
- Xcode entrypoint:
-workspace or -project
-scheme (and optional -testPlan)
- Destination(s): simulator name + iOS runtime (or
OS=latest), and whether real devices are required
- UI-test hooks: launch arguments/env toggles (stubs, demo data, auth bypass, disable animations)
- Artifact needs:
xcresult, coverage, screenshots/video, logs
Quick Commands
| Task |
Command |
| List schemes |
xcodebuild -list -workspace MyApp.xcworkspace |
| List simulators |
xcrun simctl list devices |
| List devices (USB) |
xcrun xctrace list devices |
| Boot simulator |
xcrun simctl boot "iPhone 15 Pro" |
| Wait for boot |
xcrun simctl bootstatus booted -b |
| Build app |
xcodebuild build -scheme MyApp -sdk iphonesimulator |
| Install app |
xcrun simctl install booted app.app |
| Run tests |
xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=latest' -resultBundlePath TestResults.xcresult |
| Run tests (device) |
xcodebuild test -scheme MyApp -destination 'platform=iOS,id=<UDID>' -resultBundlePath TestResults.xcresult |
| Reset simulators |
xcrun simctl shutdown all && xcrun simctl erase all |
| Take screenshot |
xcrun simctl io booted screenshot screenshot.png |
| Record video |
xcrun simctl io booted recordVideo recording.mov |
Workflow
- Resolve build inputs (
workspace/project, scheme, testPlan, destinations).
- Make simulator state repeatable: shutdown/erase as needed, boot, and wait for boot.
- Run tests with artifacts enabled (
-resultBundlePath); parallelize and retry only when appropriate.
- Triage failures from the
xcresult bundle; confirm flakes with repetition; quarantine with an owner and reproduction steps.
xcodebuild Patterns
- Select tests to reproduce:
-only-testing:TargetTests/ClassName/testMethod and -skip-testing:TargetTests/FlakyClass.
- Prefer test plans for large suites:
-testPlan <plan> (keeps device/config/runs consistent).
- Enable parallel testing when suites are isolation-safe:
-parallel-testing-enabled YES (+ -maximum-parallel-testing-workers N).
- Always write a result bundle in automation:
-resultBundlePath TestResults.xcresult.
- For reruns, split build and test:
xcodebuild build-for-testing ... then xcodebuild test-without-building ....
- Inspect results locally:
open TestResults.xcresult or xcrun xcresulttool get --path TestResults.xcresult --format json.
Flake Triage (Repetition and Retry)
- Prefer repetition to prove flake rate before adding retries.
- Use targeted reruns before suite-wide retries.
Common patterns (flags vary by Xcode version):
- Retry failing tests once in CI:
-retry-tests-on-failure -test-iterations 2
- Measure flakiness until first failure:
-test-iterations 50 -test-repetition-mode until-failure
- Run a single test repeatedly:
-only-testing:TargetTests/ClassName/testMethod -test-iterations 20
Testing Layers
| Layer |
Framework |
Scope |
| Unit |
XCTest / Swift Testing |
Business logic (fast) |
| Snapshot |
XCTest + snapshot libs |
View rendering |
| Integration |
XCTest |
Persistence, networking |
| UI |
XCUITest |
Critical user journeys |
Device Matrix
- Default: simulators for PR gates; real devices for release
- Cover: one small phone, one large phone, iPad if supported
- Add OS versions only for multiple major release support
Flake Control
Use these defaults unless the project requires otherwise:
- Disable or reduce animations in UI-test builds.
- Fix locale/timezone (via launch arguments or app-level configuration).
- Stub network at the boundary (avoid real third-party calls in UI tests).
- Reset app state between tests (fresh install, deep-link reset, or explicit teardown).
- Prefer state-based waits (
waitForExistence, expectations) over sleeps.
- Pre-grant/reset permissions where possible (simulators):
xcrun simctl privacy booted grant ....
CI Integration (GitHub Actions)
name: iOS CI
on: [push, pull_request]
jobs:
test:
runs-on: macos-15
steps:
- uses: actions/checkout@v4
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "16.0"
- run: |
set -euo pipefail
xcodebuild test \
-scheme MyApp \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=latest' \
-resultBundlePath TestResults.xcresult
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: TestResults.xcresult
Do / Avoid
Do
- Make UI tests independent and idempotent
- Use test data builders and dedicated test accounts
- Collect
xcresult bundles on failure
- Use accessibilityIdentifier, not labels
Avoid
- Relying on test ordering or global state
- UI tests requiring real network
- Thread.sleep() for synchronization
- Accepting AI-proposed selectors without validation
Resources
| Resource |
Purpose |
| references/swift-testing.md |
Swift Testing framework |
| references/simulator-commands.md |
Complete simctl reference |
| references/xctest-patterns.md |
XCTest/XCUITest patterns |
| references/xcuitest-patterns.md |
XCUITest UI testing patterns |
| references/snapshot-testing-ios.md |
Visual snapshot testing |
| references/ios-ci-optimization.md |
CI pipeline optimization |
Templates
| Template |
Purpose |
| assets/template-ios-ui-test-stability-checklist.md |
Stability checklist |
Related Skills
Fact-Checking
- Use web search/web fetch to verify current external facts, versions, pricing, deadlines, regulations, or platform behavior before final answers.
- Prefer primary sources; report source links and dates for volatile information.
- If web access is unavailable, state the limitation and mark guidance as unverified.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: qa-testing-ios3description: iOS testing with XCTest/XCUITest/Swift Testing via xcodebuild/simctl. Use when choosing destinations, controlling flakes, or parsing xcresult. Use when this capability is needed.4---56# QA Testing (iOS)78Use `xcodebuild` + Xcode Simulator (`simctl`) to build, run, and stabilize iOS tests.910**Primary docs**: [XCTest](https://developer.apple.com/documentation/xctest), [Swift Testing](https://developer.apple.com/documentation/testing), [simctl](https://developer.apple.com/documentation/xcode/simctl), [Xcode testing](https://developer.apple.com/documentation/xcode/testing-your-apps-in-xcode)1112## Inputs to Confirm1314- Xcode entrypoint: `-workspace` or `-project`15- `-scheme` (and optional `-testPlan`)16- Destination(s): simulator name + iOS runtime (or `OS=latest`), and whether real devices are required17- UI-test hooks: launch arguments/env toggles (stubs, demo data, auth bypass, disable animations)18- Artifact needs: `xcresult`, coverage, screenshots/video, logs1920## Quick Commands2122| Task | Command |23|------|---------|24| List schemes | `xcodebuild -list -workspace MyApp.xcworkspace` |25| List simulators | `xcrun simctl list devices` |26| List devices (USB) | `xcrun xctrace list devices` |27| Boot simulator | `xcrun simctl boot "iPhone 15 Pro"` |28| Wait for boot | `xcrun simctl bootstatus booted -b` |29| Build app | `xcodebuild build -scheme MyApp -sdk iphonesimulator` |30| Install app | `xcrun simctl install booted app.app` |31| Run tests | `xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=latest' -resultBundlePath TestResults.xcresult` |32| Run tests (device) | `xcodebuild test -scheme MyApp -destination 'platform=iOS,id=<UDID>' -resultBundlePath TestResults.xcresult` |33| Reset simulators | `xcrun simctl shutdown all && xcrun simctl erase all` |34| Take screenshot | `xcrun simctl io booted screenshot screenshot.png` |35| Record video | `xcrun simctl io booted recordVideo recording.mov` |3637## Workflow38391. Resolve build inputs (`workspace/project`, `scheme`, `testPlan`, destinations).402. Make simulator state repeatable: shutdown/erase as needed, boot, and wait for boot.413. Run tests with artifacts enabled (`-resultBundlePath`); parallelize and retry only when appropriate.424. Triage failures from the `xcresult` bundle; confirm flakes with repetition; quarantine with an owner and reproduction steps.4344## xcodebuild Patterns4546- Select tests to reproduce: `-only-testing:TargetTests/ClassName/testMethod` and `-skip-testing:TargetTests/FlakyClass`.47- Prefer test plans for large suites: `-testPlan <plan>` (keeps device/config/runs consistent).48- Enable parallel testing when suites are isolation-safe: `-parallel-testing-enabled YES` (+ `-maximum-parallel-testing-workers N`).49- Always write a result bundle in automation: `-resultBundlePath TestResults.xcresult`.50- For reruns, split build and test: `xcodebuild build-for-testing ...` then `xcodebuild test-without-building ...`.51- Inspect results locally: `open TestResults.xcresult` or `xcrun xcresulttool get --path TestResults.xcresult --format json`.5253### Flake Triage (Repetition and Retry)5455- Prefer repetition to prove flake rate before adding retries.56- Use targeted reruns before suite-wide retries.5758Common patterns (flags vary by Xcode version):5960- Retry failing tests once in CI: `-retry-tests-on-failure -test-iterations 2`61- Measure flakiness until first failure: `-test-iterations 50 -test-repetition-mode until-failure`62- Run a single test repeatedly: `-only-testing:TargetTests/ClassName/testMethod -test-iterations 20`6364## Testing Layers6566| Layer | Framework | Scope |67|-------|-----------|-------|68| Unit | XCTest / Swift Testing | Business logic (fast) |69| Snapshot | XCTest + snapshot libs | View rendering |70| Integration | XCTest | Persistence, networking |71| UI | XCUITest | Critical user journeys |7273### Device Matrix7475- Default: simulators for PR gates; real devices for release76- Cover: one small phone, one large phone, iPad if supported77- Add OS versions only for multiple major release support7879### Flake Control8081Use these defaults unless the project requires otherwise:8283- Disable or reduce animations in UI-test builds.84- Fix locale/timezone (via launch arguments or app-level configuration).85- Stub network at the boundary (avoid real third-party calls in UI tests).86- Reset app state between tests (fresh install, deep-link reset, or explicit teardown).87- Prefer state-based waits (`waitForExistence`, expectations) over sleeps.88- Pre-grant/reset permissions where possible (simulators): `xcrun simctl privacy booted grant ...`.8990## CI Integration (GitHub Actions)9192```yaml93name: iOS CI94on: [push, pull_request]95jobs:96 test:97 runs-on: macos-1598 steps:99 - uses: actions/checkout@v4100 - uses: maxim-lobanov/setup-xcode@v1101 with:102 xcode-version: "16.0"103 - run: |104 set -euo pipefail105 xcodebuild test \106 -scheme MyApp \107 -sdk iphonesimulator \108 -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=latest' \109 -resultBundlePath TestResults.xcresult110 - uses: actions/upload-artifact@v4111 if: always()112 with:113 name: test-results114 path: TestResults.xcresult115```116117## Do / Avoid118119### Do120121- Make UI tests independent and idempotent122- Use test data builders and dedicated test accounts123- Collect `xcresult` bundles on failure124- Use accessibilityIdentifier, not labels125126### Avoid127128- Relying on test ordering or global state129- UI tests requiring real network130- Thread.sleep() for synchronization131- Accepting AI-proposed selectors without validation132133## Resources134135| Resource | Purpose |136|----------|---------|137| [references/swift-testing.md](references/swift-testing.md) | Swift Testing framework |138| [references/simulator-commands.md](references/simulator-commands.md) | Complete simctl reference |139| [references/xctest-patterns.md](references/xctest-patterns.md) | XCTest/XCUITest patterns |140| [references/xcuitest-patterns.md](references/xcuitest-patterns.md) | XCUITest UI testing patterns |141| [references/snapshot-testing-ios.md](references/snapshot-testing-ios.md) | Visual snapshot testing |142| [references/ios-ci-optimization.md](references/ios-ci-optimization.md) | CI pipeline optimization |143144## Templates145146| Template | Purpose |147|----------|---------|148| [assets/template-ios-ui-test-stability-checklist.md](assets/template-ios-ui-test-stability-checklist.md) | Stability checklist |149150## Related Skills151152| Skill | Purpose |153|-------|---------|154| [software-mobile](../software-mobile/SKILL.md) | iOS development |155| [qa-testing-strategy](../qa-testing-strategy/SKILL.md) | Test strategy |156| [qa-testing-mobile](../qa-testing-mobile/SKILL.md) | Cross-platform mobile |157158## Fact-Checking159160- Use web search/web fetch to verify current external facts, versions, pricing, deadlines, regulations, or platform behavior before final answers.161- Prefer primary sources; report source links and dates for volatile information.162- If web access is unavailable, state the limitation and mark guidance as unverified.163164---165> Converted and distributed by [TomeVault](https://tomevault.io/claim/vasilyu1983) — claim your Tome and manage your conversions.166<!-- tomevault:4.0:skill_md:2026-04-11 -->