What it is
SnapshotTesting records views, data structures and any other value as a reference artefact and fails tests when the output changes.
assertSnapshot records on first run and compares thereafter. Strategies cover images, text descriptions, JSON and recursive dumps.
Installation
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.17.0")Getting started
The smallest useful thing you can do with it, and what each part means.
swift
import SnapshotTesting
import XCTest
final class BookRowTests: XCTestCase {
func testAppearance() {
let view = BookRow(book: .preview)
// Image snapshots across device configurations.
assertSnapshot(of: view, as: .image(layout: .device(config: .iPhone13)))
assertSnapshot(of: view, as: .image(traits: .init(userInterfaceStyle: .dark)))
// Text snapshots are readable in code review, unlike images.
assertSnapshot(of: viewModel.state, as: .dump)
assertSnapshot(of: response, as: .json)
}
}Advanced usage
Where the library earns its place over a simpler alternative.
swift
override func setUp() {
super.setUp()
// Set to .all to re-record every snapshot after an intentional change.
// Must be committed as .missing, or tests never fail.
withSnapshotTesting(record: .missing) {}
}
// Anti-aliasing differs slightly across machines and OS versions.
assertSnapshot(of: view, as: .image(precision: 0.99, perceptualPrecision: 0.98))
// Snapshot a whole request/response pair.
assertSnapshot(of: urlRequest, as: .raw)Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Snapshot does not match on CI but passes locally
- Different simulator or OS. Pin the runner's Xcode and device, and add perceptualPrecision.
- Tests always pass, even after breaking changes
- Record mode is still enabled. Set it back to .missing and commit.
Best practices
- Never commit with record mode on; the tests then always pass.
- Prefer .dump and .json over image snapshots where possible — the diffs are reviewable.
- Set a precision tolerance for image snapshots or CI will fail on rendering differences.
- Pin the simulator and OS version; snapshots are not portable across them.
Background
Why it exists, and what it was reacting to.
From Point-Free, it addresses the tedium of asserting on complex output: rather than writing fifty assertions about a view's layout, record it once and let the diff tell you what changed.
