UI Test Automation: Snapshot Testing in IOS

Beyza Budak
ÇSTech
7 min readJul 6, 2023

--

As our app evolves, designs may shift, but with snapshot tests, we’re swift to lift 🚀

1.1 Introduction

In application development, Test Engineers are always faced with the challenge of providing quality and error-free user experiences. While functional testing is important, checking the visual appearance of user interfaces (UIs) is also necessary to deliver a successful product.

Snapshot testing, by taking screenshots of UI elements and comparing them to reference images, we can quickly identify visual issues and ensure that the UI looks consistent across different devices. Besides the UI Testing technique I mentioned in my previous article, while automatically testing the user interface, snapshot tests are used to check the appearance of the application visually. Both types of testing are important testing techniques that complement each other and help improve practice quality.

In this article, we will examine snapshot testing from a Test Engineer’s perspective. We’ll discuss the benefits, explore the different types of snapshots, and learn how to set up and write snapshot tests using popular libraries. By following best practices, we can improve our user interface testing strategies and deliver better practices.

Let’s Assemble and discover the power of snapshot testing for better user experiences!

1.2 What is snapshot testing?

Snapshot testing is used to verify the visual appearance of iOS app interfaces. It involves capturing an image of a screen and comparing it with a reference image to ensure consistency. Developers can catch unintended UI changes early by incorporating snapshot testing and delivering visually consistent and high-quality apps.

1.3 How does it work?

Figure 1: Snapshot testing working principle
  • The snapshot test uses a render to take a screenshot of a screen, either through UIKit or SwiftUI. In essence, by editing the interface components and placing the contents to create the image.
  • This image is then saved as a reference and used in subsequent tests.
  • When the snapshot test is run, the saved reference image is compared with the current screenshot.
  • If any differences are detected, the test will fail and inspection is required to identify changes.
  • If the screenshot is not detected, it will throw an error and automatically save the image in the snapshot folder by giving the name of the test.
Figure 2: The test report that is automatically recorded when the test fails
Figure 3: Success sign when snapshots match and error report when they do not match

2. Implementing Snapshot Testing in iOS

To create a snapshot test in Xcode, you need to follow these steps:

  1. Create a test class: Select File -> New -> File, choose UI Test Case Class, provide a name for your class, and create it.
  2. Add the Snapshot Testing library: In the next step, you will need to add the library for Snapshot Testing. This library provides the necessary tools and functionality to perform snapshot tests.

FBSnapshotTestCase: A library developed by Facebook that has a large feature set for Snapshot tests. Although it offers many features, unfortunately, it has not received updates for a long time. And the library, whose development was discontinued later, continued to be developed by Airbnb as iOSSnapshotTestCase.

iOSSnapshotTestCase: A library for iOS snapshot tests developed by Airbnb. It provides an API similar to FBSnapshotTestCase and lets you run snapshot tests quickly and reliably.

Nimble-Snapshots: A library that uses the Quick and Nimble testing frameworks. This library allows you to write snapshot tests more descriptively and has powerful matching features.

SwiftSnapshotTesting: A library developed by Point-Free that helps developers to make it easier to write snapshot tests. This library uses a powerful DSL (Domain Specific Language) and allows writing clean and readable snapshot tests.

We chose Point-Free in our project, for the reasons for this are:

Easy to use: SwiftSnapshotTesting makes it simpler and clearer to write snapshot tests. Tests become more readable thanks to the use of a clean DSL.

Updated documentation: Point-Free provides detailed documentation explaining the use of the library. This allows developers to better understand and use the library.

Active development: It is known that the library is still actively developed and kept up to date. This provides assurance that potential issues will be fixed and new features added.

To incorporate the necessary dependencies for snapshot testing into your project, you can utilize package managers like CocoaPods or Swift Package Manager. Follow these steps to add the dependencies to your project:

  1. Install the SnapshotTesting library using your preferred package manager. For example, if you’re using CocoaPods, add the following line to your project’s Podfile:
pod 'SnapshotTesting'

or

1. Click on your project in the Xcode project navigator.

2. Select your UI Test target under the “Targets” section.

3. Go to the “Build Phases” tab.

Figure 4: Build Phases Link Binary With Libraries

4. Click on the “+” button under the “Dependencies” section to add a new dependency.

5. In the popup window, select “Add Package Dependency”.

Figure 5: Add Package Dependency

6. In the search bar, type “SnapshotTesting” and select the package from the search results.

7. Click “Add Package” to add it to your project.

Figure 6: Apple Swift Packages page

Once the library is added, import the SnapshotTesting module in your test class file:

import SnapshotTesting

Import the module of the target you want to test with snapshot tests using the @testable keyword. For example:

@testable import CiceksepetiTest
   func testSplashView() {

let splashView = SplashView()

/* We call the view that we will define here, it can be a direct
screen or we can also define small structures such as buttons,
images, etc. specifically.*/

...
}

Before we start writing our tests, let’s get to know the parameters in the library we chose.

4. Exploring Snapshot Testing Parameters

4.1 Record Parameters

Figure 7: Snapshot Record Parameters

record -> Determines whether to save the snapshot.

named -> If we add a record here, it determines the name of the recorded snapshot image. If we leave it blank, it will give the name of the test to the image and save it in the folder.

4.2 Comparison Parameters

Figure 8: Snapshot Comparison Parameters

precision -> Specifies the pixel difference precision used in the snapshot comparison.

For example, a low sensitivity value of 0.1,
0.5 compares snapshot images with higher precision than it.

Setting them depends on the test scenarios used, for example, let’s take the comment banners on the order detail page in the Çiçeksepeti application, they may be less important for us as they are dynamic and constantly changing. 0.5 can be used in this. However, we do not have the opportunity to give a low coverage on the payment page, it is both more static and one of the important pages in the application.

Figure 9: Ciceksepeti Order Detail and Payment Page

sizeTolarance -> This parameter is used for resolving differences. Device differences can be used for dynamic content, animation, and transitions.

4.3 Snapshot Types Parameters

Figure 10: Snapshot Types Parameters

image -> Save as image.

recursiveDescription -> Saves the view hierarchy as a text file.

5. Advantages and Disadvantages

Figure 11: Snapshot Testing Advantages vs Disadvantages

5.1 Advantages

  • Quickly and effectively checks the visual consistency of interface changes, with no need for extra manual control.
  • It can be easily implemented to automate tests and increase reproducibility. Once a snapshot is created, comparisons are made with reference to these snapshots in subsequent tests.
  • It can be used to check the compatibility of the app on different platforms such as different devices, screen sizes, and iOS versions. Snapshots help us verify that the app displays consistently across platforms.

5.2 Disadvantages

  • Snapshot tests are used only to check the visual accuracy of the application. If not used in conjunction with other types of testing, it may not be sufficient to fully test the functional accuracy of the application.
  • It can present challenges on changing, dynamic screens and devices with different resolutions.
  • In large and continuously developed projects, snapshot tests can be a huge maintenance cost.

If we apply the snapshot test well to the project, it will be easier for the test and developer team to detect errors and the product will come out with fewer errors. If we say how best to implement this, we should use stable tests and reference images to increase reliability. If we regularly update the reference images and test the relevant components by dividing them into smaller parts on complex screens, we will reduce the margin of error of the snapshot test as much as possible, thus minimizing the disadvantages.

In conclusion, snapshot testing offers a powerful approach to ensure the visual correctness of iOS applications. By embracing this technique and continuously refining our tests, we can enhance the quality and reliability of our software. So, why not give snapshot testing a try in your next iOS project? It’s a great way to catch visual bugs early and deliver a polished user experience. Happy testing and may your snapshots always be accurate! ☀️

References

--

--