Choose Between `simctl uninstall` and Erasing a Simulator
Uninstalling an app and erasing a simulator reset different state. Pick the smallest reset that reproduces the test condition and document what data is lost.
Reset only the state your test requires
Removing an app with simctl uninstall deletes that app's installed container but leaves the simulator's OS, other apps, and many device settings intact. Erasing a simulator resets the virtual device more broadly, including app data and system-level state. These operations answer different questions.
Use uninstall and reinstall when testing a first launch for one app while keeping the same simulator environment. Use a fresh or erased simulator when the case depends on system permissions, keychain state, or a clean OS configuration. Save any needed test fixtures before erasing.
Make the reset reproducible
Target a UDID, not whichever device happens to be booted. Capture the simulator runtime and device type alongside the test. A sequence that erases a shared developer simulator can destroy unrelated work, so automate destructive resets only for disposable CI devices or clearly named test instances.
After a reset, verify the expected state rather than assuming the command did what you intended. Check the app installation, permission status, and seeded data, then run the scenario. Keep reset commands separate from test assertions so a failure can be attributed to setup or product behavior.
If a bug appears only after an upgrade, neither uninstall nor erase is the correct reproduction; install the previous version and exercise the migration path. Choosing the right reset preserves the state that matters and prevents “works on my simulator” from meaning “works after I erased the evidence.”
Choose the reset from the question
Uninstalling an app removes its app-specific data while leaving the simulator, other apps, and much of the OS state intact. Erasing the simulator removes the entire device state, including accounts, keychain items, permissions, and installed applications. A reboot or app relaunch changes less still. Use the smallest reset that answers the test question so you do not destroy useful evidence.
For a first-run permission test, uninstall may be enough, but verify keychain persistence if the app stores credentials there. For a migration test, install the previous build, seed realistic data, upgrade without deleting the app, and assert the schema and user-visible state. For a system-level issue involving permissions, locale, or device configuration, a new simulator may be appropriate. Record the reset command and preconditions in the test case.
Do not use erase as a routine fix for every failing UI test. It increases runtime, masks state leaks, and can make a test appear reliable only because it destroys the state that triggers the bug. Keep separate fixtures for clean install, upgrade, revoked permission, and corrupted or partial data. A deterministic reset policy turns simulator state into a deliberate test input rather than an unexplained source of variation.
Record the reset operation in the test case and verify post-reset preconditions. Uninstall may leave keychain state; erase removes the whole simulator. A migration test needs neither: it needs the previous build and its data. Choosing the smallest reset preserves evidence and makes a failure reproducible for another developer or CI runner. Keep disposable CI devices separate from personal simulators.
After setup, assert installation, permissions, keychain expectations, locale, and seeded data before running the product scenario. Keep fixture setup separate from product assertions and name the reset mode in the test report. This makes a failure attributable to clean install, upgrade, revoked permission, or corrupted state instead of to an invisible simulator reset. Avoid erasing a personal simulator as a routine cleanup step.
For an upgrade case, install the previous build and seed data before the candidate. For a clean-install case, verify that no keychain or shared-container state invalidates the assumption. For a system-state case, record the runtime and device type. These preconditions answer different questions and should never be hidden behind one generic reset helper.
After setup, assert installation, permissions, keychain expectations, locale, and seeded data before running the product scenario. Keep fixture setup separate from product assertions and name the reset mode in the test report. This makes a failure attributable to clean install, upgrade, revoked permission, or corrupted state instead of to an invisible simulator reset.
Record the reset operation in the test case and verify post-reset preconditions. Uninstall may leave keychain state; erase removes the whole simulator. A migration test needs neither: it needs the previous build and its data. Choosing the smallest reset preserves evidence and makes a failure reproducible for another developer or CI runner. Keep disposable CI devices separate from personal simulators so destructive setup cannot erase useful manual test state.