A low-maintenance, simple framework for a snapshot testing, which takes into account a snapshot difference factor (must have if you're using CI).

Overview

CornSnapshotTesting

Swift 5.1 Platforms Swift Package Manager CI compatable MIT License

A low-maintenance, simple framework for a snapshot testing, which takes into account a snapshot difference factor (must have if you're using CI).

CornSnapshotTesting: snapshot testing swift library

Table of contents

  1. Installation
  2. Key Features
  3. Usage
  4. Contributing

Installation

Swift Package manager

The Swift Package Manager is a powerful tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. Therefore it's so easy to import CornSnapshotTesting dependency into your project.

  1. Open project settings.
  2. Switch to the Package Dependencies tab.
  3. Tap on + button.
  4. Past the current repository link or search for CornSnapshotTesting.

Feel free to check the official documentation to get more information about how to add a Package Dependency.

To add the CornSnapshotTesting to your Swift package, add the dependency into the Package.swift:

dependencies: [
 .package(url: "https://github.com/popcornomnom/corn-snapshot-testing.git", from: upToNextMajor(from: "1.0.0")),
]

Key Features

  • Compares the snapshot of the current window with the previously saved reference image. The assertSnapshot method is available in any sub-class of XCTestCase;
  • The test result depends on the similarity of images, taking into account the tolerance factor. It's important value if you are using CI to run your tests and have the image quality discrepancy between your local machine and the CI tool's virtual machine;
  • By default, the snapshot folder path is equal to the caller's file path. But you can change the path if necessary;
  • Reference, actual and difference images are attached to the test results as XCTAttachments. Image difference factor is also available in a test error message.
  • The difference image highlights the areas of difference between the two snapshots.

Usage

assertSnapshot

The assertSnapshot method captures the current device's window snapshot and compares it with a previously saved reference image. The reference image won't be changed in case of a failed test result. Make sure that you call the assertSnapshot method when an app is already launched.

This method accepts the next parameters:

  • delay: The time interval in seconds after which the snapshot will be taken. For example, the time needed for an animation to be completed.
  • name: The snapshot file's name. By default, this value is equal to the function name.
  • path: The path to the folder where the snapshot is placed. By default, this value is equal to the caller's file path.
  • folderComponents: Additional components of the path for subfolders.
  • interfaceStyle: The current interface appearance of the app during the test. It's used to add the current app theme to the snapshot file name.

All arguments are optional. The assertSnapshot is available for external use, but not for an override on purpose.

Example 1:

func testMainScreen() throws {
  // Given -
  // Mock dynamic content here, such as images, json responses if needed.
  // Launch the app.
  let app = XCUIApplication()
  app.launch()
   
  // When - screen is visible.
  waitUntilMainScreenIsVisible()
   
  // Then -
  // Asserts snapshot with name `testMainScreen-iPhone-8.png` 
  // by `${current-file-path}\Snapshots\` path after 0 seconds.
  assertSnapshot()
}

Test case: After stackView spacing has been changed +30pt:

Reference Actual Difference

error message

Example 2:

func testMainScreenInDarkMode() throws {
  // Given - stab the current user interface.
  let app = XCUIApplication()
  app.launch(interfaceStyle: .dark)
  //
  // When - screen is visible.
  waitUntilMainScreenIsVisible()
   
  // Then
  // Asserts snapshot with name "custom-name-dark-iPhone-8.png",
  // by `${current-file-path}\Snapshots\Main screen` path,
  // after 2 seconds.
  assertSnapshot(delay: 2, name: "custom name",
          folderComponents: "Main screen",
          interfaceStyle: .dark)
}

tolerance

An example of changing tolerance factor:

CornSnapshotConfiguration.current.tolerance = 0.25 // tolerance used for Bitrise CI

By default, the tolerance value is 0, meaning CornSnapshotTesting framework expects snapshots to match pixel-to-pixel. If you use the CI tool to run tests, you may have a difference in the image quality between devices. Therefore, I would recommend using a higher tolerance value (for instance 0.25).

higlighterColor

CornSnapshotConfiguration.current.higlighterColor = .yellow

The color used by the difference image to highlight the areas of difference between the two snapshots. By default higlighterColor is red.

Important

To replace the reference image remove the previous one and run the test once more.

How to check failed tests

You can find a reference, actual and difference images in failed test artifacts. The image similarity factor is also available in the corresponding test results.

Name structure of the snapshot:

{snapshot name}-{theme}-{device name}.png

This name convention was chosen on purpose taking into account that if attachments sorted by name, all images related to one test will be grouped together.

Contributing

During CornSnapshotTesting framework development I aimed to include essential functionality into 1.0.0 version, to make it convenient to integrate into any project. With this intent, I've added only SPM support because it's available in any Xcode project. Also, I kept a few more points for improvement unimplemented.

If some functionality is missing, or you have any suggestions on how to improve the framework or you have time to make CornSnapshotTesting better by helping with the implementation of points bellow, feel free to create the Pull Request, Issue or ask me directly. (PR should be in suggestions format and shouldn't break the core logic).

What's not there yet

  • CocoaPods, Carthage support;
  • macOS, tvOS support;
  • Integration tests support - Asserting the current simulator window helps to keep the snapshot testing independent from the project implementation, but it would be nice to have assertSnapshot(view: UIView, delay: _, name: _, folderComponents: _, interfaceStyle: _) method in place;
  • Tests.

Footnotes

From the author

I hope publishing this framework as open-source will make a contribution to the community and help someone to save time by using what I've written and tested.

Credits

A heartfelt thanks to Miloskiy for the awesome design! Also thanks to @Chieh Wang for help by suggesting to dig more into Vision direction.

Your support has made this project happen.

Licence

MIT


Blog popcornomnom.com  ·  GitHub @popcornomnom  ·  Linkedin @popcornomnom

You might also like...
This is a notebook which can feel your emotion!

EmotionNote This is a notebook which can feel your emotion! Making you know better about yourself. Choose or take a photo of your face, the app will t

An extension to SnapshotTesting which allows you to create HEIC images

🗜 SnapshotTestingHEIC An extension to SnapshotTesting which allows you to create HEIC images. The benefit of using HEIC instead of PNG is that it can

DGCropImage - A photo cropping tool which mimics Photo.app written by Swift
DGCropImage - A photo cropping tool which mimics Photo.app written by Swift

DGCropImage A photo cropping tool which mimics Photo.app written by Swift. This

STDevRxExt contains some extension functions for RxSwift and RxCocoa which makes our live easy.

STDevRxExt Example To run the Example.playground, clone the repo, and run pod install from the Example directory first. Requirements iOS 9.0+ tvOS 9.0

Media view which subclasses UIImageView, and can display & load images, videos, GIFs, and audio and from the web, and has functionality to minimize from fullscreen, as well as show GIF previews for videos.
Media view which subclasses UIImageView, and can display & load images, videos, GIFs, and audio and from the web, and has functionality to minimize from fullscreen, as well as show GIF previews for videos.

I've built out the Swift version of this library! Screenshots Description ABMediaView can display images, videos, as well as now GIFs and Audio! It su

Get  a photo which has effects like the system camera’s Portrait mode (on compatible devices).
Get a photo which has effects like the system camera’s Portrait mode (on compatible devices).

Blurring background like Portrait mode in the iPhone camera If we want to have the blurring effect like the Portrait mode in the iOS Camera app. What

SwiftUI iOS app which applies CoreML Video Matting (background removal) model to the front camera stream
SwiftUI iOS app which applies CoreML Video Matting (background removal) model to the front camera stream

CoreML Camera Video Matting This is a simple iOS app which applies Video Matting (background removal) model to the front camera stream. Video Matting

GPUImage 3 is a BSD-licensed Swift framework for GPU-accelerated video and image processing using Metal.
GPUImage 3 is a BSD-licensed Swift framework for GPU-accelerated video and image processing using Metal.

GPUImage 3 Janie Clayton http://redqueengraphics.com @RedQueenCoder Brad Larson http://www.sunsetlakesoftware.com @bradlarson contact@sunsetlakesoftwa

Releases(v1.0.0)
Owner
Rita
🍏 iOS Developer 🍏
Rita
A view that takes a set of images, make transition from one to another by using flipping effects.

CDFlipView A view that takes a set of images, make transition from one to another by using flipping effects. Demo Live Demo: https://appetize.io/app/w

Jianbin LIN 99 Aug 27, 2021
Simple CLI utility to save off an image from every webcam hooked into a mac

macOSCameraCapture Simple CLI utility to save off an image from every webcam connected to the macOS machine. This utility is meant for research and te

Cody Thomas 12 Jan 26, 2022
EbImagesSwiftUI - SDWebImageSwiftUI - a SwiftUI image loading framework, which based on SDWebImage

SDWebImageSwiftUI What's for SDWebImageSwiftUI is a SwiftUI image loading framew

An Tran 1 Jan 6, 2022
FlickrSearchPhotos - Simple search photos application which uses Flickr REST API made in Swift

FlickrSearchPhotos - Simple search photos application which uses Flickr REST API made in Swift

 Mihai Erős 1 Jun 6, 2022
This package integrates a UIImagePickerController into a SwiftUI app.

This Swift Package integrates a UIImagePickerController into a SwiftUI app and allows a user to select, scale and position an image to be cropped and saved as a conatct's photo, similar to the stock iOS Contacts app.

Rillieux 58 Dec 26, 2022
Combine SnapshotTesting images into a single asset

An extension to SnapshotTesting which allows you to create images combining the output of multiple snapshot strategies, assuming they all output to UIImage.

James Sherlock 41 Nov 28, 2022
Turn a photo of your food into a face

Megabite Megabite is a mobile app that automatically turns a photo of your food into a face. Read more about it here. Installation This project uses C

Aaron Randall 361 Oct 26, 2022
Roll marbles into set positions on screen

Marble-Tilt Roll Marbles into set positions on screen Paul Hudson Hacking with Swift - project 26 - Took most of the code and created my own spin on i

Scott Mayhew 0 Dec 11, 2021
A simple macOS app to read code from images, written purely in Swift using Vision Framework.

CodeReader A simple macOS app to read code from images, written purely in Swift using Vision Framework. Usage Drag an image Click the convert button R

Md Ibrahim Hassan 44 Nov 20, 2022
Simple command-line utility for performing OCR using Apple's Vision framework

ocrit Runs Vision's OCR on input images and outputs corresponding txt files for each image, or writes the recognized results to standard output. USAGE

Guilherme Rambo 61 Nov 23, 2022