Set Up Snapshots
Set up snapshots for any Apple app using Snapshot Previews or your preferred snapshot library.
This feature is available only if you're in the Early Adopter program. Features available to Early Adopters are still in-progress and may have bugs. We recognize the irony.
Set up Snapshots for your Apple app. Generate snapshots locally or in your own CI using your preferred snapshot library, then upload the generated images to Sentry for image diffing, visual review, and GitHub status checks.
On Apple you can either generate snapshots from previews (recommended) or from an existing snapshot tool like swift-snapshot-testing.
These methods are not mutually exclusive — you can generate and upload snapshots from your previews and any existing snapshot tests.
SnapshotPreviews automatically turns every #Preview and PreviewProvider in your project into a snapshot, so you don't have to maintain explicit snapshot tests.
Create a test that subclasses SnapshotTest:
import SnapshottingTests
class YourAppSnapshotTest: SnapshotTest {
// Return nil to snapshot all previews, or an array of preview
// names (regex supported) to include.
override class func snapshotPreviews() -> [String]? { nil }
// Return preview names to exclude, or nil.
override class func excludedSnapshotPreviews() -> [String]? { nil }
}
Set TEST_RUNNER_SNAPSHOTS_EXPORT_DIR before running the tests so SnapshotPreviews writes images to disk instead of attaching them to the XCTest result bundle:
export TEST_RUNNER_SNAPSHOTS_EXPORT_DIR="$PWD/snapshot-images"
Continue to Step 2.
Use this path if you already generate snapshots with another tool. sentry-cli is directory-based — any tool that writes PNG or JPEG files to a directory works.
If you use Point-Free's swift-snapshot-testing, set the record environment variable so CI always writes fresh images for upload:
export TEST_RUNNER_SNAPSHOT_TESTING_RECORD=all
Images land in __Snapshots__/<TestClass>/ next to your test file — that's the directory you upload to Sentry.
In record mode, swift-snapshot-testing reports every test as a "failure" because it's recording rather than comparing. Use continue-on-error: true on your CI test step so the upload step still runs.
For a full working setup, see the swift-snapshot-testing CI workflow in our Hacker News sample app.
Continue to Step 2.
Any tool that produces PNG or JPEG images works — custom XCTest render helpers, other open-source libraries, or manual screenshot workflows. Point your upload command at the directory your tool writes to. See Uploading Snapshots for the expected file and metadata layout.
Run your snapshot tests, then upload the resulting directory with sentry-cli:
export TEST_RUNNER_SNAPSHOTS_EXPORT_DIR="$PWD/snapshot-images"
xcodebuild test \
-scheme YourScheme \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' \
-only-testing:YourAppTests/YourAppSnapshotTest \
CODE_SIGNING_ALLOWED=NO
sentry-cli build snapshots --app-id com.example.your-app $TEST_RUNNER_SNAPSHOTS_EXPORT_DIR
Replace the path with the directory your library writes to (for swift-snapshot-testing, that's YourAppTests/__Snapshots__/YourSnapshotTests). See Uploading Snapshots for the full CLI reference and metadata schema.
Once the local upload succeeds, wire the same commands into your CI. See Integrating Into CI for the general GitHub Actions structure.
For end-to-end examples, see the workflows in our Hacker News sample app:
- SnapshotPreviews workflow — builds once, fans out across multiple simulators in a matrix, then aggregates all images into a single upload.
- swift-snapshot-testing workflow — records all snapshots in one job and uploads them via the Sentry Fastlane plugin.
You have two options for uploading snapshots from CI. Pick the one that fits your existing workflow.
Call sentry-cli build snapshots directly from your workflow — the same command you ran in Step 2. This is the simplest option if you aren't already using Fastlane.
If your CI already uses Fastlane, you can use the Sentry Fastlane plugin instead of calling sentry-cli directly.
- Install the Sentry Fastlane plugin:
bundle exec fastlane add_plugin fastlane-plugin-sentry
- Add an upload lane to your
Fastfile:
Fastfiledesc 'Upload snapshots to Sentry'
lane :upload_snapshots do |options|
sentry_upload_snapshots(
path: options[:path],
app_id: 'com.example.your-app',
auth_token: ENV['SENTRY_AUTH_TOKEN'],
org_slug: 'your-org',
project_slug: 'your-project'
)
end
- Call the lane after your test step in CI:
- name: Upload snapshots to Sentry
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: bundle exec fastlane upload_snapshots --path $TEST_RUNNER_SNAPSHOTS_EXPORT_DIR
Set the --path option to the directory where your snapshot library writes its output.
For a working example, see the upload_sentry_snapshots lane in the Hacker News sample app's Fastfile.
- Pin your simulator device and Xcode version. Use the same simulator model, OS, and Xcode across CI runs to avoid spurious diffs caused by rendering differences.
- Isolate snapshot tests. Put them in a dedicated test class or test plan so you can run them independently with
-only-testing. - Build once, run many. If you snapshot across multiple simulators,
xcodebuild build-for-testingonce and share the products with downstreamtest-without-buildingjobs — see the SnapshotPreviews workflow for a working pattern.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").