📸 Delightful Swift snapshot testing.
4,330
stars
389
commits
Swift
primary language
Aug 24, 2026
updated
Delightful Swift snapshot testing.
Once installed, no additional configuration is required. You can import the
SnapshotTesting module and call the assertSnapshot function.
import SnapshotTesting
import Testing
@MainActor
struct MyViewControllerTests {
@Test func myViewController() {
let vc = MyViewController()
assertSnapshot(of: vc, as: .image)
}
}
When an assertion first runs, a snapshot is automatically recorded to disk and the test will fail, printing out the file path of any newly-recorded reference.
❌ failed - No reference was found on disk. Automatically recorded snapshot: …
open "…/MyAppTests/__Snapshots__/MyViewControllerTests/testMyViewController.png"
Re-run "testMyViewController" to test against the newly-recorded snapshot.
Repeat test runs will load this reference and compare it with the runtime value. If they don't match, the test will fail and describe the difference. Failures can be inspected from Xcode's Report Navigator or by inspecting the file URLs of the failure.
You can record a new reference by customizing snapshots inline with the assertion, or using the
withSnapshotTesting tool:
// Record just this one snapshot
assertSnapshot(of: vc, as: .image, record: .all)
// Record all snapshots in a scope:
withSnapshotTesting(record: .all) {
assertSnapshot(of: vc1, as: .image)
assertSnapshot(of: vc2, as: .image)
assertSnapshot(of: vc3, as: .image)
}
// Record all snapshot failures in a Swift Testing suite:
@Suite(.snapshots(record: .failed))
struct FeatureTests {}
// Record all snapshot failures in an 'XCTestCase' subclass:
class FeatureTests: XCTestCase {
override func invokeTest() {
withSnapshotTesting(record: .failed) {
super.invokeTest()
}
}
}
While most snapshot testing libraries in the Swift community are limited to UIImages of UIViews,
SnapshotTesting can work with any format of any value on any Swift platform!
The assertSnapshot function accepts a value and any snapshot strategy that value supports. This
means that a view or view controller can be tested against an image representation and against a
textual representation of its properties and subview hierarchy.
assertSnapshot(of: vc, as: .image)
assertSnapshot(of: vc, as: .recursiveDescription)
View testing is highly configurable. You can override trait collections (for specific size classes and content size categories) and generate device-agnostic snapshots, all from a single simulator.
assertSnapshot(of: vc, as: .image(on: .iPhoneSe))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneSe))
assertSnapshot(of: vc, as: .image(on: .iPhoneSe(.landscape)))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneSe(.landscape)))
assertSnapshot(of: vc, as: .image(on: .iPhoneX))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneX))
assertSnapshot(of: vc, as: .image(on: .iPadMini(.portrait)))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPadMini(.portrait)))
Warning Snapshots must be compared using the exact same simulator that originally took the reference to avoid discrepancies between images.
Better yet, SnapshotTesting isn't limited to views and view controllers! There are a number of available snapshot strategies to choose from.
For example, you can snapshot test URL requests (e.g., those that your API client prepares).
assertSnapshot(of: urlRequest, as: .raw)
// POST http://localhost:8080/account
// Cookie: pf_session={"userId":"1"}
//
// email=blob%40pointfree.co&name=Blob
And you can snapshot test Encodable values against their JSON and property list representations.
assertSnapshot(of: user, as: .json)
// {
// "bio" : "Blobbed around the world.",
// "id" : 1,
// "name" : "Blobby"
// }
assertSnapshot(of: user, as: .plist)
// <?xml version="1.0" encoding="UTF-8"?>
// <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
// "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
// <plist version="1.0">
// <dict>
// <key>bio</key>
// <string>Blobbed around the world.</string>
// <key>id</key>
// <integer>1</integer>
// <key>name</key>
// <string>Blobby</string>
// </dict>
// </plist>
In fact, any value can be snapshot-tested by default using its mirror!
assertSnapshot(of: user, as: .dump)
// ▿ User
// - bio: "Blobbed around the world."
// - id: 1
// - name: "Blobby"
If your data can be represented as an image, text, or data, you can write a snapshot test for it!
The latest documentation is available here.
Warning By default, Xcode will try to add the SnapshotTesting package to your project's main application/framework target. Please ensure that SnapshotTesting is added to a test target instead, as documented in the last step, below.
https://github.com/pointfreeco/swift-snapshot-testing.If you want to use SnapshotTesting in any other project that uses
SwiftPM, add the package as a dependency in Package.swift:
dependencies: [
.package(
url: "https://github.com/pointfreeco/swift-snapshot-testing",
from: "1.12.0"
),
]
Next, add SnapshotTesting as a dependency of your test target:
targets: [
.target(name: "MyApp"),
.testTarget(
name: "MyAppTests",
dependencies: [
"MyApp",
.product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
]
)
]
UIViews and CALayers. Write snapshots against any value.isRecording mode is true or not.Codable support. Snapshot encodable data structures into their JSON and property list
representations.SnapshotTesting.diffToolCommand = { "ksdiff \($0) \($1)" }
AccessibilitySnapshot adds easy regression testing for iOS accessibility.
AccessibilitySnapshotColorBlindness adds snapshot strategies for color blindness simulation on iOS views, view controllers and images.
GRDBSnapshotTesting adds snapshot strategy for testing SQLite database migrations made with GRDB.
Nimble-SnapshotTesting adds Nimble matchers for SnapshotTesting to be used by Swift Package Manager.
Prefire generating Snapshot Tests via
Swift Package Plugins
using SwiftUI Preview
PreviewSnapshots share View
configurations between SwiftUI Previews and snapshot tests and generate several snapshots with a
single test assertion.
swift-html is a Swift DSL for type-safe,
extensible, and transformable HTML documents and includes an HtmlSnapshotTesting module to
snapshot test its HTML documents.
swift-snapshot-testing-nimble adds Nimble matchers for SnapshotTesting.
swift-snapshot-testing-stitch adds the ability to stitch multiple UIView's or UIViewController's together in a single test.
SnapshotTestingDump Adds support to
use swift-custom-dump by using customDump
strategy for Any
SnapshotTestingHEIC adds image support using the HEIC storage format which reduces file sizes in comparison to PNG.
SnapshotVision adds snapshot strategy for text recognition on views and images. Uses Apples Vision framework.
Have you written your own SnapshotTesting plug-in? Add it here and submit a pull request!
iOSSnapshotTestCase helped introduce screen
shot testing to a broad audience in the iOS community. Experience with it inspired the creation
of this library.
Jest brought generalized snapshot testing to the JavaScript community with a polished user experience. Several features of this library (diffing, automatically capturing new snapshots) were directly influenced.
SnapshotTesting was designed with witness-oriented programming.
This concept (and more) are explored thoroughly in a series of episodes on Point-Free, a video series exploring functional programming and Swift hosted by Brandon Williams and Stephen Celis.
Witness-oriented programming and the design of this library was explored in the following Point-Free episodes:
This library is released under the MIT license. See LICENSE for details.
(top 30 of 98)
Swift
95.7%
HTML
4.1%
📸 Delightful Swift snapshot testing.
4,330
stars
389
commits
Swift
primary language
Aug 24, 2026
updated
Delightful Swift snapshot testing.
Once installed, no additional configuration is required. You can import the
SnapshotTesting module and call the assertSnapshot function.
import SnapshotTesting
import Testing
@MainActor
struct MyViewControllerTests {
@Test func myViewController() {
let vc = MyViewController()
assertSnapshot(of: vc, as: .image)
}
}
When an assertion first runs, a snapshot is automatically recorded to disk and the test will fail, printing out the file path of any newly-recorded reference.
❌ failed - No reference was found on disk. Automatically recorded snapshot: …
open "…/MyAppTests/__Snapshots__/MyViewControllerTests/testMyViewController.png"
Re-run "testMyViewController" to test against the newly-recorded snapshot.
Repeat test runs will load this reference and compare it with the runtime value. If they don't match, the test will fail and describe the difference. Failures can be inspected from Xcode's Report Navigator or by inspecting the file URLs of the failure.
You can record a new reference by customizing snapshots inline with the assertion, or using the
withSnapshotTesting tool:
// Record just this one snapshot
assertSnapshot(of: vc, as: .image, record: .all)
// Record all snapshots in a scope:
withSnapshotTesting(record: .all) {
assertSnapshot(of: vc1, as: .image)
assertSnapshot(of: vc2, as: .image)
assertSnapshot(of: vc3, as: .image)
}
// Record all snapshot failures in a Swift Testing suite:
@Suite(.snapshots(record: .failed))
struct FeatureTests {}
// Record all snapshot failures in an 'XCTestCase' subclass:
class FeatureTests: XCTestCase {
override func invokeTest() {
withSnapshotTesting(record: .failed) {
super.invokeTest()
}
}
}
While most snapshot testing libraries in the Swift community are limited to UIImages of UIViews,
SnapshotTesting can work with any format of any value on any Swift platform!
The assertSnapshot function accepts a value and any snapshot strategy that value supports. This
means that a view or view controller can be tested against an image representation and against a
textual representation of its properties and subview hierarchy.
assertSnapshot(of: vc, as: .image)
assertSnapshot(of: vc, as: .recursiveDescription)
View testing is highly configurable. You can override trait collections (for specific size classes and content size categories) and generate device-agnostic snapshots, all from a single simulator.
assertSnapshot(of: vc, as: .image(on: .iPhoneSe))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneSe))
assertSnapshot(of: vc, as: .image(on: .iPhoneSe(.landscape)))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneSe(.landscape)))
assertSnapshot(of: vc, as: .image(on: .iPhoneX))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneX))
assertSnapshot(of: vc, as: .image(on: .iPadMini(.portrait)))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPadMini(.portrait)))
Warning Snapshots must be compared using the exact same simulator that originally took the reference to avoid discrepancies between images.
Better yet, SnapshotTesting isn't limited to views and view controllers! There are a number of available snapshot strategies to choose from.
For example, you can snapshot test URL requests (e.g., those that your API client prepares).
assertSnapshot(of: urlRequest, as: .raw)
// POST http://localhost:8080/account
// Cookie: pf_session={"userId":"1"}
//
// email=blob%40pointfree.co&name=Blob
And you can snapshot test Encodable values against their JSON and property list representations.
assertSnapshot(of: user, as: .json)
// {
// "bio" : "Blobbed around the world.",
// "id" : 1,
// "name" : "Blobby"
// }
assertSnapshot(of: user, as: .plist)
// <?xml version="1.0" encoding="UTF-8"?>
// <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
// "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
// <plist version="1.0">
// <dict>
// <key>bio</key>
// <string>Blobbed around the world.</string>
// <key>id</key>
// <integer>1</integer>
// <key>name</key>
// <string>Blobby</string>
// </dict>
// </plist>
In fact, any value can be snapshot-tested by default using its mirror!
assertSnapshot(of: user, as: .dump)
// ▿ User
// - bio: "Blobbed around the world."
// - id: 1
// - name: "Blobby"
If your data can be represented as an image, text, or data, you can write a snapshot test for it!
The latest documentation is available here.
Warning By default, Xcode will try to add the SnapshotTesting package to your project's main application/framework target. Please ensure that SnapshotTesting is added to a test target instead, as documented in the last step, below.
https://github.com/pointfreeco/swift-snapshot-testing.If you want to use SnapshotTesting in any other project that uses
SwiftPM, add the package as a dependency in Package.swift:
dependencies: [
.package(
url: "https://github.com/pointfreeco/swift-snapshot-testing",
from: "1.12.0"
),
]
Next, add SnapshotTesting as a dependency of your test target:
targets: [
.target(name: "MyApp"),
.testTarget(
name: "MyAppTests",
dependencies: [
"MyApp",
.product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
]
)
]
UIViews and CALayers. Write snapshots against any value.isRecording mode is true or not.Codable support. Snapshot encodable data structures into their JSON and property list
representations.SnapshotTesting.diffToolCommand = { "ksdiff \($0) \($1)" }
AccessibilitySnapshot adds easy regression testing for iOS accessibility.
AccessibilitySnapshotColorBlindness adds snapshot strategies for color blindness simulation on iOS views, view controllers and images.
GRDBSnapshotTesting adds snapshot strategy for testing SQLite database migrations made with GRDB.
Nimble-SnapshotTesting adds Nimble matchers for SnapshotTesting to be used by Swift Package Manager.
Prefire generating Snapshot Tests via
Swift Package Plugins
using SwiftUI Preview
PreviewSnapshots share View
configurations between SwiftUI Previews and snapshot tests and generate several snapshots with a
single test assertion.
swift-html is a Swift DSL for type-safe,
extensible, and transformable HTML documents and includes an HtmlSnapshotTesting module to
snapshot test its HTML documents.
swift-snapshot-testing-nimble adds Nimble matchers for SnapshotTesting.
swift-snapshot-testing-stitch adds the ability to stitch multiple UIView's or UIViewController's together in a single test.
SnapshotTestingDump Adds support to
use swift-custom-dump by using customDump
strategy for Any
SnapshotTestingHEIC adds image support using the HEIC storage format which reduces file sizes in comparison to PNG.
SnapshotVision adds snapshot strategy for text recognition on views and images. Uses Apples Vision framework.
Have you written your own SnapshotTesting plug-in? Add it here and submit a pull request!
iOSSnapshotTestCase helped introduce screen
shot testing to a broad audience in the iOS community. Experience with it inspired the creation
of this library.
Jest brought generalized snapshot testing to the JavaScript community with a polished user experience. Several features of this library (diffing, automatically capturing new snapshots) were directly influenced.
SnapshotTesting was designed with witness-oriented programming.
This concept (and more) are explored thoroughly in a series of episodes on Point-Free, a video series exploring functional programming and Swift hosted by Brandon Williams and Stephen Celis.
Witness-oriented programming and the design of this library was explored in the following Point-Free episodes:
This library is released under the MIT license. See LICENSE for details.
(top 30 of 98)
Swift
95.7%
HTML
4.1%