SnapshotTesting comes with a wide variety of snapshot strategies for a varienty of platforms. To extend these strategies or define your own, see Defining Custom Snapshot Strategies.
If you'd like to submit your own custom strategy, see Contributing.
Any
CALayer
CaseIterable
CGPath
Encodable
NSBezierPath
NSImage
NSView
NSViewController
SCNScene
SKScene
String
UIBezierPath
UIImage
UIView
UIViewController
URLRequest
Platforms: All
A snapshot strategy that captures a value's textual description from String
's init(description:)
initializer.
Format: String
assertSnapshot(matching: user, as: .description)
Records:
User(bio: "Blobbed around the world.", id: 1, name: "Blobby")
See also: .dump
.
A snapshot strategy for comparing any structure based on a sanitized text dump.
The reference format looks a lot like the output of Swift's built-in dump
function, though it does its best to make output deterministic by stripping out pointer memory addresses and sorting non-deterministic data, like dictionaries and sets.
You can hook into how an instance of a type is rendered in this strategy by conforming to the AnySnapshotStringConvertible
protocol and defining the snapshotDescription
property.
Format: String
assertSnapshot(matching: user, as: .dump)
Records:
▿ User
- bio: "Blobbed around the world."
- id: 1
- name: "Blobby"
See also: .description
.
Platforms: iOS, macOS, tvOS
A snapshot strategy for comparing layers based on pixel equality.
Format: NSImage
, UIImage
-
precision: Float = 1
The percentage of pixels that must match.
// Match reference perfectly.
assertSnapshot(matching: layer, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: layer, as: .image(precision: 0.99))
Platforms: All
A snapshot strategy for functions on CaseIterable
types. It feeds every possible input into the function and puts the inputs and outputs into a CSV table.
Format: Comma-separated values (CSV)
A snapshotting strategy on the output of the function you are snapshotting.
enum Direction: String, CaseIterable {
case up, down, left, right
var rotatedLeft: Direction {
switch self {
case .up: return .left
case .down: return .right
case .left: return .down
case .right: return .up
}
}
}
assertSnapshot(
matching: { $0.rotatedLeft },
as: Snapshotting<Direction, String>.func(into: .description)
)
Records:
"up","left"
"down","right"
"left","down"
"right","up"
Platforms: iOS, macOS, tvOS
A snapshot strategy for comparing paths based on pixel equality.
Format: NSImage
, UIImage
-
precision: Float = 1
The percentage of pixels that must match.
// Match reference perfectly.
assertSnapshot(matching: path, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: path, as: .image(precision: 0.99))
A snapshot strategy for comparing paths based on a description of their elements.
Format: String
-
numberFormatter: NumberFormatter
The number formatter used for formatting points (default: 1-3 fraction digits).
// Match reference perfectly.
assertSnapshot(matching: path, as: .elementsDescription)
// Match reference as formatted by formatter.
assertSnapshot(matching: path, as: .elementsDescription(numberFormatter: NumberFormatter()))
Platforms: All
A snapshot strategy for comparing encodable structures based on their JSON representation.
Format: String
encoder: JSONEncoder
(optional)
assertSnapshot(matching: user, as: .json)
Records:
{
"bio" : "Blobbed around the world.",
"id" : 1,
"name" : "Blobby"
}
A snapshot strategy for comparing encodable structures based on their property list representation.
Format: String
encoder: PropertyListEncoder
(optional)
assertSnapshot(matching: user, as: .plist)
Records:
<?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>
Platforms: macOS
A snapshot strategy for comparing paths based on pixel equality.
Format: NSImage
-
precision: Float = 1
The percentage of pixels that must match.
// Match reference perfectly.
assertSnapshot(matching: path, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: path, as: .image(precision: 0.99))
A snapshot strategy for comparing paths based on a description of their elements.
Format: String
-
numberFormatter: NumberFormatter
The number formatter used for formatting points (default: 1-3 fraction digits).
// Match reference perfectly.
assertSnapshot(matching: path, as: .elementsDescription)
// Match reference as formatted by formatter.
assertSnapshot(matching: path, as: .elementsDescription(numberFormatter: NumberFormatter()))
Platforms: macOS
A snapshot strategy for comparing images based on pixel equality.
Format: NSImage
-
precision: Float = 1
The percentage of pixels that must match.
// Match reference as-is.
assertSnapshot(matching: image, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: image, as: .image(precision: 0.99))
Platforms: macOS
A snapshot strategy for comparing layers based on pixel equality.
Note: Snapshots must be compared on the same OS as the device that originally took the reference to avoid discrepancies between images.
Format: NSImage
Note: Includes SCNView
, SKView
, WKWebView
.
-
precision: Float = 1
The percentage of pixels that must match.
-
size: CGSize = nil
A view size override.
// Match reference as-is.
assertSnapshot(matching: view, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: view, as: .image(precision: 0.99))
// Render at a certain size.
assertSnapshot(
matching: view,
as: .image(size: .init(width: 44, height: 44))
)
A snapshot strategy for comparing views based on a recursive description of their properties and hierarchies.
Format: String
assertSnapshot(matching: view, as: .recursiveDescription)
Records:
[ AF LU ] h=--- v=--- NSButton "Push Me" f=(0,0,77,32) b=(-)
[ A LU ] h=--- v=--- NSButtonBezelView f=(0,0,77,32) b=(-)
[ AF LU ] h=--- v=--- NSButtonTextField "Push Me" f=(10,6,57,16) b=(-)
A=autoresizesSubviews, C=canDrawConcurrently, D=needsDisplay, F=flipped, G=gstate, H=hidden (h=by ancestor), L=needsLayout (l=child needsLayout), U=needsUpdateConstraints (u=child needsUpdateConstraints), O=opaque, P=preservesContentDuringLiveResize, S=scaled/rotated, W=wantsLayer (w=ancestor wantsLayer), V=needsVibrancy (v=allowsVibrancy), #=has surface
Note: Snapshots must be compared on the same OS as the device that originally took the reference to avoid discrepancies between images.
A snapshot strategy for comparing layers based on pixel equality.
Format: NSImage
-
precision: Float = 1
The percentage of pixels that must match.
-
size: CGSize = nil
A view size override.
// Match reference as-is.
assertSnapshot(matching: vc, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: vc, as: .image(precision: 0.99))
// Render at a certain size.
assertSnapshot(
matching: vc,
as: .image(size: .init(width: 640, height: 480))
)
See also: NSView
.
A snapshot strategy for comparing view controller views based on a recursive description of their properties and hierarchies.
Format: String
assertSnapshot(matching: vc, as: .recursiveDescription)
Records:
[ AF LU ] h=--- v=--- NSButton "Push Me" f=(0,0,77,32) b=(-)
[ A LU ] h=--- v=--- NSButtonBezelView f=(0,0,77,32) b=(-)
[ AF LU ] h=--- v=--- NSButtonTextField "Push Me" f=(10,6,57,16) b=(-)
A=autoresizesSubviews, C=canDrawConcurrently, D=needsDisplay, F=flipped, G=gstate, H=hidden (h=by ancestor), L=needsLayout (l=child needsLayout), U=needsUpdateConstraints (u=child needsUpdateConstraints), O=opaque, P=preservesContentDuringLiveResize, S=scaled/rotated, W=wantsLayer (w=ancestor wantsLayer), V=needsVibrancy (v=allowsVibrancy), #=has surface
A snapshot strategy for comparing SceneKit scenes based on pixel equality.
Platforms: iOS, macOS, tvOS
-
precision: Float = 1
The percentage of pixels that must match.
-
size: CGSize
The size of the scene.
assertSnapshot(
matching: scene,
as: .image(size: .init(width: 640, height: 480))
)
A snapshot strategy for comparing SpriteKit scenes based on pixel equality.
Platforms: iOS, macOS, tvOS
-
precision: Float = 1
The percentage of pixels that must match.
-
size: CGSize
The size of the scene.
assertSnapshot(
matching: scene,
as: .image(size: .init(width: 640, height: 480))
)
Platforms: All
A snapshot strategy for comparing strings based on equality.
Format: String
assertSnapshot(matching: htmlString, as: .lines)
Platforms: iOS, tvOS
A snapshot strategy for comparing paths based on pixel equality.
Format: UIImage
-
precision: Float = 1
The percentage of pixels that must match.
// Match reference perfectly.
assertSnapshot(matching: path, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: path, as: .image(precision: 0.99))
A snapshot strategy for comparing paths based on a description of their elements.
Format: String
-
numberFormatter: NumberFormatter
The number formatter used for formatting points (default: 1-3 fraction digits).
// Match reference perfectly.
assertSnapshot(matching: path, as: .elementsDescription)
// Match reference as formatted by formatter.
assertSnapshot(matching: path, as: .elementsDescription(numberFormatter: NumberFormatter()))
Platforms: iOS, tvOS
A snapshot strategy for comparing images based on pixel equality.
Format: UIImage
-
precision: Float = 1
The percentage of pixels that must match.
// Match reference as-is.
assertSnapshot(matching: image, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: image, as: .image(precision: 0.99))
Platforms: iOS, tvOS
A snapshot strategy for comparing layers based on pixel equality.
Note: Snapshots must be compared using a simulator with the same OS, device gamut, and scale as the simulator that originally took the reference to avoid discrepancies between images.
Format: UIImage
Note: Includes SCNView
, SKView
, WKWebView
.
-
drawHierarchyInKeyWindow: Bool = false
Utilize the simulator's key window in order to render
UIAppearance
andUIVisualEffect
s. This option requires a host application for your tests and will not work for framework test targets. -
precision: Float = 1
The percentage of pixels that must match.
-
size: CGSize = nil
A view size override.
-
traits: UITraitCollection = .init()
A trait collection override.
// Match reference as-is.
assertSnapshot(matching: view, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: view, as: .image(precision: 0.99))
// Render at a certain size.
assertSnapshot(
matching: view,
as: .image(size: .init(width: 44, height: 44))
)
// Render with a horizontally-compact size class.
assertSnapshot(
matching: view,
as: .image(traits: .init(horizontalSizeClass: .regular))
)
A snapshot strategy for comparing views based on a recursive description of their properties and hierarchies.
Format: String
-
size: CGSize = nil
A view size override.
-
traits: UITraitCollection = .init()
A trait collection override.
// Layout on the current device.
assertSnapshot(matching: view, as: .recursiveDescription)
// Layout with a certain size.
assertSnapshot(matching: view, as: .recursiveDescription(size: .init(width: 22, height: 22)))
// Layout with a certain trait collection.
assertSnapshot(matching: view, as: .recursiveDescription(traits: .init(horizontalSizeClass: .regular)))
Records:
<UIButton; frame = (0 0; 22 22); opaque = NO; layer = <CALayer>>
| <UIImageView; frame = (0 0; 22 22); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer>>
Platforms: iOS, tvOS
A snapshot strategy for comparing view controllers based on their embedded controller hierarchy.
Format: String
assertSnapshot(matching: vc, as: .hierarchy)
Records:
<UITabBarController>, state: appeared, view: <UILayoutContainerView>
| <UINavigationController>, state: appeared, view: <UILayoutContainerView>
| | <UIPageViewController>, state: appeared, view: <_UIPageViewControllerContentView>
| | | <UIViewController>, state: appeared, view: <UIView>
| <UINavigationController>, state: disappeared, view: <UILayoutContainerView> not in the window
| | <UIViewController>, state: disappeared, view: (view not loaded)
| <UINavigationController>, state: disappeared, view: <UILayoutContainerView> not in the window
| | <UIViewController>, state: disappeared, view: (view not loaded)
| <UINavigationController>, state: disappeared, view: <UILayoutContainerView> not in the window
| | <UIViewController>, state: disappeared, view: (view not loaded)
| <UINavigationController>, state: disappeared, view: <UILayoutContainerView> not in the window
| | <UIViewController>, state: disappeared, view: (view not loaded)
A snapshot strategy for comparing layers based on pixel equality.
Note: Snapshots must be compared using a simulator with the same OS, device gamut, and scale as the simulator that originally took the reference to avoid discrepancies between images.
Format: UIImage
-
drawHierarchyInKeyWindow: Bool = false
Utilize the simulator's key window in order to render
UIAppearance
andUIVisualEffect
s. This option requires a host application for your tests and will not work for framework test targets.Incompatible with the
on
parameter. -
on: ViewImageConfig
A set of device configuration settings.
Incompatible with the
drawHierarchyInKeyWindow
parameter. -
precision: Float = 1
The percentage of pixels that must match.
-
size: CGSize = nil
A view size override.
-
traits: UITraitCollection = .init()
A trait collection override.
// Match reference as-is.
assertSnapshot(matching: vc, as: .image)
// Allow for a 1% pixel difference.
assertSnapshot(matching: vc, as: .image(precision: 0.99))
// Render as if on a certain device.
assertSnapshot(matching: vc, as: .image(on: .iPhoneX(.portrait)))
// Render at a certain size.
assertSnapshot(
matching: vc,
as: .image(size: .init(width: 375, height: 667))
)
// Render with a horizontally-compact size class.
assertSnapshot(
matching: vc,
as: .image(traits: .init(horizontalSizeClass: .compact))
)
// Match reference as-is.
assertSnapshot(matching: vc, as: .image)
See also: UIView
.
A snapshot strategy for comparing view controller views based on a recursive description of their properties and hierarchies.
Format: String
-
on: ViewImageConfig
A set of device configuration settings.
-
size: CGSize = nil
A view size override.
-
traits: UITraitCollection = .init()
A trait collection override.
// Layout on the current device.
assertSnapshot(matching: vc, as: .recursiveDescription)
// Layout as if on a certain device.
assertSnapshot(matching: vc, as: .recursiveDescription(on: .iPhoneSe(.portrait)))
Records:
<UIView; frame = (0 0; 375 667); opaque = NO; layer = <CALayer>>
| <UIImageView; frame = (0 0; 375 667); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer>>
Platforms: All
A snapshot strategy for comparing requests based on a cURL representation.
Format: String
assertSnapshot(matching: request, as: .curl)
Records:
curl \
--request POST \
--header "Accept: text/html" \
--data 'pricing[billing]=monthly&pricing[lane]=individual' \
"https://www.pointfree.co/subscribe"
A snapshot strategy for comparing requests based on raw equality.
Format: String
assertSnapshot(matching: request, as: .raw)
Records:
POST http://localhost:8080/account
Cookie: pf_session={"userId":"1"}
email=blob%40pointfree.co&name=Blob