Intro (0:00)
What is snapshot testing?
In snapshot testing, a view is rendered and saved into a repository. When the test is run, the tool re-creates and re-renders that view and does a comparison.
What can you test?
You can test states of your views, such as when it’s highlighted, or perhaps with more text. You can also test your view against different screen sizes.
Demo (3:19)
I’ve created a simple example with a view controller. The view has a title that animates, a body, and a button. This project is on GitHub
We’ll use SnapshotEngine as a wrapper, and Nimble-Snapshots to help with writing our tests.
Create a class that inherits from QuickSpec.
import UIKit
import Quick
import Nimble
import Cartography
@testable import cmduconf
class ST_View: QuickSpec {
// Note: Return 'true' to regenerate the snapshots of this class
override var recordingMode: Bool {
return false
}
let delegate = ViewController()
override func spec() {
describe("A View") {
context("on a 4' screen") {
let view = View(delegate: self.delegate)
constrain(view) { view in
view.width == 320
view.height == 568
}
it("has a valid snapshot") {
expect(view).to(self.validateSnapshot())
}
}
context("on a 5.5' screen") {
let view = View(delegate: self.delegate)
constrain(view) { view in
view.width == 414
view.height == 736
}
it("has a valid snapshot") {
expect(view).to(self.validateSnapshot())
}
}
}
}
}
This test will fail because we don’t have a snapshot saved. Change the following line to true to save a snapshot to the repository.
// Note: Return 'true' to regenerate the snapshots of this class
override var recordingMode: Bool {
return true
}
By changing the boolean back to false, the test will pass.
What happens under the hood?
It creates a snapshot by capturing the view and saving it to the repository. If the color of the view is changed, the test will fail.
These tests are created by a Facebook library, called FB Snapshot Test Case. The library creates a CGContextRef, and then creates another based on the saved snapshot. By rendering the view again, it compares both images on a memory level with a C function.
Concerns (10:45)
- Architecture
- You can test your view controllers, but if you isolate your views and separate them from the view controllers, that will be ideal.
- Asynchronicity
- If your views need network connectivity to work properly, it will be hard to test. To combat this, try to have methods that load a view without requiring a network connection.
- Autolayout
- Use autolayout. Views without autolayout requires the frame to be set.
- Repo Space
- Testing this way takes up repo space which can get clogged, and can take longer if its a large project.
Questions (16:35)
How can snapshot testing deal with animations?
You cannot test if something will change. You can only test the view in a fixed moment in time.
What is the difference between using snapshot testing versus UI testing for Xcode?
Firstly, snapshot testing is much faster. It runs with your unit tests so it’s not as if it runs the unit test and then runs the UI test. Secondly it doesn’t have to run the app so it’s faster that way.
Receive news and updates from Realm straight to your inbox