read

Tools are evolving.

Fastlane snapshot now uses Xcode 7 most awesome feature - UI Testing!

Xcode UI Testing

If you are not familiar what this awesome feature from Xcode 7 is, then watch WWDC 2015 for a demo.

In short, developers can now:

  • record UI interactions
  • replay and test
  • view test report which includes screenshots at every stage
  • view test report which includes code coverage too

How to use

There is a good UI Testing Cheat Sheet and Example from masilotti.

More (and lengthy) details from Apple Doc.

Using with snapshot

Setting up snapshot with a UI Test target is easy. The few steps are provided in it’s quick guide.

What snapshot did not point (perhaps obvious) is this:

Snapshot will run every test case in the UI test target. Therefore, you should have 2 UI test targets:

  1. For full UI testing (if you need)
  2. For snapshot to capture screenshots

The test target for snapshot would suffice with 1 test case that walk through the important screens that you need to capture. Maybe 1, if you support only iPhone and not iPad/etc.

Testing iPad vs iPhone

Another caveat is that snapshot will run through all devices you specified in your Snapfile.

That means, your test case could fail if your iPhone interface is different from iPad interface.

To workaround, you should have 2 test cases in snapshot test target:

func testSnapshotPhone() {
    guard UIDevice.currentDevice().userInterfaceIdiom == .Phone else { return }
    // Capture screenshots for iPhone
}

func testSnapshotPad() {
    guard UIDevice.currentDevice().userInterfaceIdiom == .Pad else { return }
    // Capture screenshots for iPad
}

Prefill Database

A common requirement when taking screenshots is to have a prefill database so that the screenshots are consistent.

You might think that can you clean up Core Data, then manually add objects in the test case setUp() function. That won’t work.

This is because the test target is not the same as app target.

You could use a backdoor, or simply provide a logic in your app to know when it is run via snapshot:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    if NSUserDefaults.standardUserDefaults().boolForKey("FASTLANE_SNAPSHOT") {
        // Prefill database
    }
}

Image

@samwize

¯\_(ツ)_/¯

Back to Home