Automate iOS Simulator Smoke Tests with `simctl`
Use a small xcrun simctl script to create a clean simulator, install an app, launch it, collect a screenshot, and preserve useful logs.
A simulator script should be disposable
Manual simulator testing accumulates state. Permissions, keychains, cached data, and an old app installation can make a regression appear or disappear. For a smoke test, a disposable simulator is easier to reason about than a favorite device that has been used for weeks.
First inspect the names supported by the installed Xcode:
xcrun simctl list devicetypes
xcrun simctl list runtimesThe device type and runtime are separate identifiers. Copying a runtime name from one machine to another can fail when Xcode versions differ, so keep the discovery command close to the script.
Create, boot, install, launch
The minimal sequence is:
DEVICE_ID=$(xcrun simctl create "Smoke Test" "iPhone 16" "iOS 18.5")
trap 'xcrun simctl shutdown "$DEVICE_ID"; xcrun simctl delete "$DEVICE_ID"' EXIT
xcrun simctl boot "$DEVICE_ID"
xcrun simctl bootstatus "$DEVICE_ID" -b
xcrun simctl install "$DEVICE_ID" build/Build/Products/Debug-iphonesimulator/App.app
xcrun simctl launch "$DEVICE_ID" com.example.appbootstatus -b gives the script a reliable wait point. Without it, an install or launch can race the simulator boot and produce an intermittent failure that looks like an application problem.
Capture evidence before cleanup
Capture a screenshot and relevant logs before the trap deletes the device:
xcrun simctl io "$DEVICE_ID" screenshot /tmp/smoke-test.png
xcrun simctl spawn "$DEVICE_ID" log show --last 2m --style compact \
--predicate 'process == "com.example.app"'For deterministic tests, seed only the state the scenario needs. A script that creates a clean device but then depends on a manually configured account is not reproducible. Consider adding simctl privacy, simctl status_bar, or a controlled launch argument when the test requires it.
Do not treat a successful process launch as a passing user flow. Add a UI test, a screenshot comparison, or a log assertion that represents the behavior you care about. The shell script is the environment harness; it is not the assertion.
The iOS simctl Workflow Generator creates a disposable-device starting point with cleanup, install, launch, screenshot, and log commands. Check the device and runtime names against the local Xcode installation before running it.