iOS UI Testing with Fastlane snapshot tool

This week I played a little bit with UI testing on Xcode. This goes without saying that I had to go through some ordeal. (More about it in later paragraphs)

So the app I build for UI testing is simple. Description goes below.

  1. You have list of countries to choose from the tableView
  2. Choose one option from the list and it takes you to the next screen
  3. Input required fields and press submit button
  4. A alert asks you for a confirmation if you want to submit the form
  5. Clicking yes will take you to the next screen which will show the dummy confirmation that form has been submitted

As mentioned on various blog posts and Apple developer forum, I first tried to record UI tests with automated tool and clicking through sequence of action buttons. However, I noticed that it is not flexible enough and you lose control over what you want to test

So finally I decided to zero in on writing UI tests manually. As hard it may sound, it was fun and you get to learn lot many things. In all I had 3 screens

  1. Select a country screen
  2. Input field
  3. Confirmation screen

Here is the sample of my UI test.


import XCTest

class JKUITestingDemoUITests: XCTestCase {
    
    let app = XCUIApplication()
    
    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        setupSnapshot(app)
        app.launch()
    }
    
    func testFormSubmission() {
        XCTAssert(app.staticTexts["Choose Country"].exists)
        XCTAssert(app.navigationBars["Choose Country"].exists)
        XCTAssert(app.staticTexts["India"].exists)
        snapshot("01FirstScreen")
        app.tables.staticTexts["India"].tap()
        
        let inputNameTextField = app.textFields["myname"]
        XCTAssert(inputNameTextField.exists)
        inputNameTextField.tap()
        inputNameTextField.typeText("Jayesh Kawli")
        
        app.tables.containingType(.Table, identifier: <#t##string?#>)
        let slider = app.sliders["myslider"]
        slider.adjustToNormalizedSliderPosition(0.9)
        let switch2 = app.switches["myswitch"]
        switch2.tap()
        app.buttons["YES"].tap()
        snapshot("02SecondScreen")
        app.buttons["Submit"].tap()
        app.alerts["Submit Profile"].buttons["YES"].tap()
        
        snapshot("03ThirdScreen")
        app.navigationBars["Jayesh Kawli"].buttons["India"].tap()
        app.navigationBars["India"].buttons["Choose Country"].tap()
    }
}

This code is filled with additional code to facilitate snapshot tool

  1. setupSnapshot(XCUIApplication()) allows you to setup snapshot with an application running UI tests

  2. snapshot("03ThirdScreen") actually takes the snapshot of current screen UI tests are running on. For e.g. if you are on the second screen, you might want to take the snapshot even before user taps the submit button to transition to the next screen.

  3. Remember that the string you mention in the snapshot call is the unique name the screenshot will be generated with. For e.g. if you create a snapshot with name snapshot("03ThirdScreen"), and devices it is running on is say iPhone5 and iPhone6 it will create two screenshots for each combination with names viz.

  • For iPhone5
    1. iPhone5-01FirstScreen
    2. iPhone5-02SecondScreen
    3. iPhone5-03ThirdScreen

  • For iPhone6
    1. iPhone6-01FirstScreen
    2. iPhone6-02SecondScreen
    3. iPhone6-03ThirdScreen

Here are screenshots of the app generated by the Snapshot

On iPhone5

home

value_input

submission

On iPhone6

home

value_input

submission

You can find the GitHub repo on UI testing demo and snapshot tool usage address. Let me know if you have any questions, comments or queries about UI Testing on iOS.