Skip to content

Latest commit

 

History

History
897 lines (571 loc) · 19.7 KB

Available-Snapshot-Strategies.md

File metadata and controls

897 lines (571 loc) · 19.7 KB

Available Snapshot Strategies

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.

List of Available Snapshot Strategies

Any

Platforms: All

.description

A snapshot strategy that captures a value's textual description from String's init(description:) initializer.

Format: String

Example:

assertSnapshot(matching: user, as: .description)

Records:

User(bio: "Blobbed around the world.", id: 1, name: "Blobby")

See also: .dump.

.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

Example:

assertSnapshot(matching: user, as: .dump)

Records:

▿ User
  - bio: "Blobbed around the world."
  - id: 1
  - name: "Blobby"

See also: .description.

CALayer

Platforms: iOS, macOS, tvOS

.image

A snapshot strategy for comparing layers based on pixel equality.

Format: NSImage, UIImage

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

Example:

// Match reference perfectly.
assertSnapshot(matching: layer, as: .image)

// Allow for a 1% pixel difference.
assertSnapshot(matching: layer, as: .image(precision: 0.99))

CaseIterable

Platforms: All

.func(into:)

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)

Parameters:

A snapshotting strategy on the output of the function you are snapshotting.

Example:

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" 

CGPath

Platforms: iOS, macOS, tvOS

.image

A snapshot strategy for comparing paths based on pixel equality.

Format: NSImage, UIImage

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

Example:

// Match reference perfectly.
assertSnapshot(matching: path, as: .image)

// Allow for a 1% pixel difference.
assertSnapshot(matching: path, as: .image(precision: 0.99))

.elementsDescription

A snapshot strategy for comparing paths based on a description of their elements.

Format: String

Parameters:

  • numberFormatter: NumberFormatter

    The number formatter used for formatting points (default: 1-3 fraction digits).

Example:

// Match reference perfectly.
assertSnapshot(matching: path, as: .elementsDescription)

// Match reference as formatted by formatter.
assertSnapshot(matching: path, as: .elementsDescription(numberFormatter: NumberFormatter()))

Encodable

Platforms: All

.json

A snapshot strategy for comparing encodable structures based on their JSON representation.

Format: String

Parameters:

  • encoder: JSONEncoder (optional)

Example:

assertSnapshot(matching: user, as: .json)

Records:

{
  "bio" : "Blobbed around the world.",
  "id" : 1,
  "name" : "Blobby"
}

.plist

A snapshot strategy for comparing encodable structures based on their property list representation.

Format: String

Parameters:

  • encoder: PropertyListEncoder (optional)

Example:

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>

NSBezierPath

Platforms: macOS

.image

A snapshot strategy for comparing paths based on pixel equality.

Format: NSImage

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

Example:

// Match reference perfectly.
assertSnapshot(matching: path, as: .image)

// Allow for a 1% pixel difference.
assertSnapshot(matching: path, as: .image(precision: 0.99))

.elementsDescription

A snapshot strategy for comparing paths based on a description of their elements.

Format: String

Parameters:

  • numberFormatter: NumberFormatter

    The number formatter used for formatting points (default: 1-3 fraction digits).

Example:

// Match reference perfectly.
assertSnapshot(matching: path, as: .elementsDescription)

// Match reference as formatted by formatter.
assertSnapshot(matching: path, as: .elementsDescription(numberFormatter: NumberFormatter()))

NSImage

Platforms: macOS

.image

A snapshot strategy for comparing images based on pixel equality.

Format: NSImage

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

Example:

// Match reference as-is.
assertSnapshot(matching: image, as: .image)

// Allow for a 1% pixel difference.
assertSnapshot(matching: image, as: .image(precision: 0.99))

NSView

Platforms: macOS

.image

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.

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

  • size: CGSize = nil

    A view size override.

Example:

// 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))
)

.recursiveDescription

A snapshot strategy for comparing views based on a recursive description of their properties and hierarchies.

Format: String

Example

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

NSViewController

Note: Snapshots must be compared on the same OS as the device that originally took the reference to avoid discrepancies between images.

.image

A snapshot strategy for comparing layers based on pixel equality.

Format: NSImage

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

  • size: CGSize = nil

    A view size override.

Example:

// 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.

.recursiveDescription

A snapshot strategy for comparing view controller views based on a recursive description of their properties and hierarchies.

Format: String

Example

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

SCNScene

.image

A snapshot strategy for comparing SceneKit scenes based on pixel equality.

Platforms: iOS, macOS, tvOS

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

  • size: CGSize

    The size of the scene.

Example:

assertSnapshot(
  matching: scene,
  as: .image(size: .init(width: 640, height: 480))
)

See also: NSView, UIView.

SKScene

.image

A snapshot strategy for comparing SpriteKit scenes based on pixel equality.

Platforms: iOS, macOS, tvOS

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

  • size: CGSize

    The size of the scene.

Example:

assertSnapshot(
  matching: scene,
  as: .image(size: .init(width: 640, height: 480))
)

See also: NSView, UIView.

String

Platforms: All

.lines

A snapshot strategy for comparing strings based on equality.

Format: String

Example:

assertSnapshot(matching: htmlString, as: .lines)

UIBezierPath

Platforms: iOS, tvOS

.image

A snapshot strategy for comparing paths based on pixel equality.

Format: UIImage

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

Example:

// Match reference perfectly.
assertSnapshot(matching: path, as: .image)

// Allow for a 1% pixel difference.
assertSnapshot(matching: path, as: .image(precision: 0.99))

.elementsDescription

A snapshot strategy for comparing paths based on a description of their elements.

Format: String

Parameters:

  • numberFormatter: NumberFormatter

    The number formatter used for formatting points (default: 1-3 fraction digits).

Example:

// Match reference perfectly.
assertSnapshot(matching: path, as: .elementsDescription)

// Match reference as formatted by formatter.
assertSnapshot(matching: path, as: .elementsDescription(numberFormatter: NumberFormatter()))

UIImage

Platforms: iOS, tvOS

.image

A snapshot strategy for comparing images based on pixel equality.

Format: UIImage

Parameters:

  • precision: Float = 1

    The percentage of pixels that must match.

Example:

// Match reference as-is.
assertSnapshot(matching: image, as: .image)

// Allow for a 1% pixel difference.
assertSnapshot(matching: image, as: .image(precision: 0.99))

UIView

Platforms: iOS, tvOS

.image

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.

Parameters:

  • drawHierarchyInKeyWindow: Bool = false

    Utilize the simulator's key window in order to render UIAppearance and UIVisualEffects. 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.

Example:

// 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))
)

.recursiveDescription

A snapshot strategy for comparing views based on a recursive description of their properties and hierarchies.

Format: String

Parameters:

  • size: CGSize = nil

    A view size override.

  • traits: UITraitCollection = .init()

    A trait collection override.

Example

// 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>>

UIViewController

Platforms: iOS, tvOS

.hierarchy

A snapshot strategy for comparing view controllers based on their embedded controller hierarchy.

Format: String

Example

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)

.image

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

Parameters:

  • drawHierarchyInKeyWindow: Bool = false

    Utilize the simulator's key window in order to render UIAppearance and UIVisualEffects. 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.

Example:

// 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.

.recursiveDescription

A snapshot strategy for comparing view controller views based on a recursive description of their properties and hierarchies.

Format: String

Parameters:

  • on: ViewImageConfig

    A set of device configuration settings.

  • size: CGSize = nil

    A view size override.

  • traits: UITraitCollection = .init()

    A trait collection override.

Example

// 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>>

URLRequest

Platforms: All

.curl

A snapshot strategy for comparing requests based on a cURL representation.

Format: String

Example:

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"

.raw

A snapshot strategy for comparing requests based on raw equality.

Format: String

Example:

assertSnapshot(matching: request, as: .raw)

Records:

POST http://localhost:8080/account
Cookie: pf_session={"userId":"1"}

email=blob%40pointfree.co&name=Blob