SoatDev IT Consulting
SoatDev IT Consulting
  • About us
  • Expertise
  • Services
  • How it works
  • Contact Us
  • News
  • June 28, 2023
  • Rss Fetcher

How to setup the library and implement the first snapshot test cases for iOS apps

Photo by Tim Mossholder on Unsplash

Several companies offer digital services through web and mobile applications. In this digital era, ensuring an application delivers on its promises is crucial for the business’s success. Users expect uninterrupted access to services such as making purchases, completing bank transfers, or requesting a taxi whenever needed. Encountering bugs is a frustrating experience for customers, potentially leading them to abandon the service or switch to a competitor’s app.

In a development team, it’s not enough to only ensure that the application works according to the business rules in the first implementation. It’s essential to protect the software from unwanted behavior that can be introduced by other developers when modifying or adding functionalities. To achieve this, automated tests are a powerful development tool, enabling the identification of behavior failures without manual intervention.

Among the various automated testing approaches, one such method is Snapshot Testing. This test consists of capturing images of the application’s screens and comparing them with new images obtained during the test execution to verify the occurrence of undesired changes. This test checks various visual elements such as texts, fonts, colors, and spacing. The goal is not to test the application logic but rather to verify if the view is presented correctly according to the expected outcome.

In this article, we will explore the iOSSnapshotTestCase library, learn how to set it up in an iOS project and discover best practices for implementing Snapshot Tests using Swift. To illustrate the concepts, we will use a simple application with a single screen displaying a list of countries. The project follows the MVVM (Model-View-ViewModel) standard and employs a protocol-oriented architecture that applies the dependency inversion principle, ensuring the application’s testability. The source code is available on GitHub.

Disclaimer: This article provides an overview of Snapshot Tests and explains the functionality of the iOSSnapshotTestCase library. It does not serve as a recommendation or guide for making technical decisions regarding adopting this testing method. It’s always necessary to consider the problem at hand and carefully evaluate the inclusion of any methodology or tool in the project, including its costs and potential side effects. Snapshot Tests can be resource-intensive and may impact the development process if implemented without proper consideration. Therefore, they should not be implemented indiscriminately.

With this in mind, it is valuable to comprehend how the library functions, thus expanding our range of available tools.

The iOSSnapshotTestCase Library

IOSSnapshotTestCase (previously FBSnapshotTestCase) is a library originally developed by Facebook and currently maintained by Uber. It can generate screen snapshots from the UIViews and compare them against reference images stored in the source code repository. When differences are detected between the captured and reference images, the test fails, and an image highlighting the discrepancies is automatically generated for debugging purposes.

To incorporate the IOSSnapshotTestCase library into your project, open the project’s Podfile and add the library as a dependency by including the following lines:

target "CountryListTests" do
use_frameworks!
pod 'iOSSnapshotTestCase'
end

After including the library, you must run the pod install command in the project folder to incorporate the dependency.

Note: If you use Carthage or Swift Package Manager, you can include the library by following the instructions in the official iOSSnapshotTestCase repository.

Next, you must configure the environment variables required for storing the reference and differential images in the project’s repository. To do this, follow these steps:

  1. Access ‘Product → Scheme → Edit Scheme’ in XCode.
  2. Navigate to the ‘Run’ tab.
  3. Add the following variables to the scheme:

XCode Environment settings

Note: It is crucial to define the environment variables in the Run scheme rather than the Test scheme. Otherwise, the generation of images will not occur correctly.

Creating Snapshot Test Cases

First, let’s add a file to the test folder to assist with test configurations. This file will simplify the creation of diff and reference image folders in the repository and prevent issues arising from directly calling snapshot library functions.

Next, we can write our first test case. It’s important to note that snapshot tests aim to verify the behavior of the view layer and do not involve testing the application’s business logic. Additionally, asynchronous tasks such as HTTP calls should be avoided in a test scenario to prevent test slowness and intermittent results.

To isolate the ViewController that needs testing, we need to define a class that mocks the behavior of the ViewModel layer. Since the application components are based on protocols, we can easily implement the CountryListViewModeling protocol to create a mock for the ViewModel class. Here’s what that looks like:

With the mocked ViewModel in place, we can proceed to write the first snapshot test for our application:

The test involves defining an array of countries and creating mock objects for the ViewModel and the system under test (sut), which refers to the ViewController being tested. Next, we call the presentCountries function to display the screen to the user. Finally, we use the verifyViewController helper function to run the snapshot test.

Upon running the test for the first time, we encounter the following error message:

snapshot comparison failed: optional(error domain… unable to load reference image)
No reference image error

It occurs because no reference image is available for comparison with the screen being tested. Therefore, we need to generate the reference image by adding a configuration to the test’s setUp function in the CountryListViewControllerUITests class:

After adding the setUp function and rerunning the test, a new error message is displayed:

failed — test ran in record mode. reference image now saved. disable record mode to perform an actual snapshot comparison
Record mode error

This error indicates that the reference image has been generated correctly, allowing us to proceed with the test. To do this, we must either remove the previously defined setUp function or set the recordMode flag value to false. Then you can rerun the test to check if it succeeds. Here’s what a successful test looks like:

code with a green checkmark in the top-left corner
Successful test

Well done! Every time the automated tests are run, whether on a local machine or a CI pipeline, it will ensure that the ViewController continues to display the expected results.

Let’s consider a scenario where another developer unintentionally deletes the line that configures the cell’s images:

When running the test after this change, a failure is observed with the message: ‘failed — Snapshot comparison failed.’ Additionally, navigate to the project folder at CountryListTests → FailureDiffs → CountryListTests.CountryListViewControllerUITests, you can access the reference images, the image obtained in the last test, and the image highlighting the differences. This greatly facilitates the debugging process.

Reference image, new image and differences

Important: In projects with a CI configuration that automatically runs unit and UI tests upon opening a pull request, it is crucial to commit and upload the files to the remote repository to ensure correct execution. Additionally, when updating screens due to changes in business rules, it is necessary to update the reference images associated with those screens.

To update the reference images, simply enable the desired test classes with the recordMode flag. This mode allows the snapshot library to capture the current state of the screens and save them as new reference images. By following this process, you can ensure that the reference images stay updated with the latest changes in the application’s UI.

Testing Different Scenarios

An intriguing aspect of snapshot testing is the ability to test different screen states by manipulating the input data. While we previously defined a test function for the success case of displaying a list of countries, it would also be valuable to include a test case for scenarios where no countries are available, resulting in an error message being displayed:

The test case for the empty country list is quite similar to the previous one, with the only distinction being an empty country array. By running the test with the recordMode flag enabled, we can verify that another reference image is generated in the folder CountryListTests → ReferenceImages_64 → CountryListTests.CountryListViewControllerUITests. Subsequently, running the test with the recordMode flag disabled should yield successful results for both written tests.

Error screen snapshot image

Conclusion

Snapshot testing is a robust tool for developers, offering assistance in safeguarding against inadvertent changes infiltrating the application’s user interfaces. This article introduced the IOSSnapshotTestCase library and showcased its fundamental implementation for snapshot testing. By employing this library, developers can ensure the integrity and consistency of their iOS projects, delivering enhanced user experiences.

Thanks for reading! If you have any questions, please leave a reply.

Resources

GitHub Repository

IOSSnapshotTestCase library


iOSSnapshotTestCase: A Guide to Snapshot Testing in iOS Projects was originally published in Better Programming on Medium, where people are continuing the conversation by highlighting and responding to this story.

Previous Post
Next Post

Recent Posts

  • From LLMs to hallucinations, here’s a simple guide to common AI terms
  • Octonions sometimes associate
  • Looking for keys under the lamppost
  • Why Intempus thinks robots should have a human physiological state
  • 48 hours left: What you won’t want to miss at the 20th TechCrunch Disrupt in October

Categories

  • Industry News
  • Programming
  • RSS Fetched Articles
  • Uncategorized

Archives

  • May 2025
  • April 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023

Tap into the power of Microservices, MVC Architecture, Cloud, Containers, UML, and Scrum methodologies to bolster your project planning, execution, and application development processes.

Solutions

  • IT Consultation
  • Agile Transformation
  • Software Development
  • DevOps & CI/CD

Regions Covered

  • Montreal
  • New York
  • Paris
  • Mauritius
  • Abidjan
  • Dakar

Subscribe to Newsletter

Join our monthly newsletter subscribers to get the latest news and insights.

© Copyright 2023. All Rights Reserved by Soatdev IT Consulting Inc.