Clicky

iOS Dev Nugget 293 iOSSnapshotTestCase (was FBSnapshotTestCase)

.

Need to run a code review on your codebase? Hire me

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.

  1. Add the iOSSnapshotTestCase pod with Cocoapods for your test target, run pod install
  2. In Xcode, go to Product > Schemes > Edit Scheme, choose Test, add these to Environment 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.

  3. Create a test class, but subclass FBSnapshotTestCase instead of XCTestCase.

  4. In the test function, create your view controller/view and call FBSnapshotVerifyView() passing in the view to test
  5. In setUp(), set recordMode to true and run the test case to create and store the reference screenshots in FB_REFERENCE_IMAGE_DIR. You'd want to make sure these screenshots represent how your app should behave.
  6. 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 in IMAGE_DIFF_DIR.
  7. 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

.

.

Like this and want such iOS dev nuggets to be emailed to you, weekly?

Sign Me Up! or follow @iosdevnuggets on Twitter

.

View archives of past issues