For most iOS apps, displaying the right data in the right way is very important. Traditionally, testing this is hard. It gets especially more complicated as your app feature set grows and you no longer know if a change affects another screen(s).
iOSSnapshotTestCase helps with that by letting us write snapshot tests, or what I like to call "screenshot-based asserts". You write tests cases with it, creating or navigating to the desired screen and then take a screenshot with it, comparing that to a reference screenshot which you made earlier.
It's easy to get started.
- Add the iOSSnapshotTestCase pod with Cocoapods for your test target, run
pod install
-
In Xcode, go to
Product
>Schemes
>Edit Scheme
, chooseTest
, add these toEnvironment Variables
:FB_REFERENCE_IMAGE_DIR
=$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/Snapshots/ReferenceImages
IMAGE_DIFF_DIR
=$(SOURCE_ROOT)$/(PROJECT_NAME)Tests/Snapshots/FailureDiffs
Make sure that
$(PROJECT_NAME)Tests
matches your test folder name in your project directory, otherwise tweak the path accordingly.The former will be used to store your reference images and the latter the results if they don't match.
-
Create a test class, but subclass
FBSnapshotTestCase
instead ofXCTestCase
. - In the test function, create your view controller/view and call
FBSnapshotVerifyView()
passing in the view to test - In
setUp()
, setrecordMode
totrue
and run the test case to create and store the reference screenshots inFB_REFERENCE_IMAGE_DIR
. You'd want to make sure these screenshots represent how your app should behave. - From now on, run it with
recordMode = false
to compare against the reference screenshots — until you intentionally change your UI and you would need to update your reference snapshot(s). If a test fails, the result, including the difference will be stored inIMAGE_DIFF_DIR
. - You want to add
IMAGE_DIFF_DIR
to your.gitignore
file.
e.g of a test class:
class AnExampleSnapshotTest: FBSnapshotTestCase {
override func setUp() {
super.setUp()
//Set to true only when creating reference snapshots
//This line should not be checked into version control
recordMode = true
}
func testExample() {
//TODO create data, set up controller, etc
let controller = MyViewController()
//This will create a reference snapshot or compare against one, depending on the value of `recordMode`
FBSnapshotVerifyView(controller.view)
}
}
Your feedback is valuable: Do you want more nuggets like this? Yes or No
.
.