Snapshot Testing in SwiftUI

Snapshot Testing, we can call it as It's a way to make sure our code changes does not affect the UI on the app.

If you add snapshot testing support to test by using UIView and UIViewController, It will also let you use them with SwiftUI as well.

There is some strategy that you can take into consideration. They will allow to handle such points of your images.

Using the Image Strategy

  • drawHierarchyInKeyWindow: Bool = false: Renders the view on the simulator’s Key Window and uses its appearance and visual effects.

  • on: ViewImageConfig: Lets you choose a variety of devices as the ViewImageConfigoption.

  • precision: Float = 1: Indicates the percentage of pixels that must match for the test to pass. By default, it’s 1, which means 100% of the pixels must match.

  • size: CGSize = nil: The view size for generating the snapshot of the test view.

  • traits: UITraitCollection = .init(): Allows you to specify a plethora of traits to test with

let view: UIView = UIHostingController(rootView: swiftUIRowView).view

Before you can test your view, you need to generate a baseline snapshot.

assertSnapshot(matching: view, as: .image(size: view.intrinsicContentSize))

assertSnapshot(matching:as:) is similar to XCTAssert.

Passing view as the matching parameter to tell SnapshotTesting which view you want to test. You’ve also directed SnapshotTesting to use the .imagestrategy, meaning it will actually save a graphical representation of your UI view at its intrinsic content size.

The image generated with an intrinsic content size might be larger than the iPhone’s width and/or height, depending on its contents. Therefore, it’s best to specify the appropriate size explicitly before testing a view.

After creating baseline snapshots, tests will start successing.

Updating baseline snapshots

To make this add the following line just above assertSnapshot(matching:as:)

isRecording = true

It will tell the SnapshotTesting framework that you want to create a new baseline snapshot. It will fail at first but then SnapshotTesting will save a new baseline snapshot.

After saving baseline snapshot, do not forget to remove the line isRecording = true again.

Testing for Specific iPhone Model

Add below method to specific an iPhone Model as a screen size.

assertSnapshot(
  matching: viewController,
  as: .image(on: .iPhoneX))

Testing for Device Orientation

To set landscape mode, add following method. .iPhoneX(.landscape) or .iPhoneX(.portrait)

assertSnapshot(
  matching: viewController,
  as: .image(on: .iPhoneX(.landscape)))

Thanks for reading this. Stay up to date for other sharings.