iOS Automation: XCUITest + Gherkin

41
iOS Automation XCUITest + Gherkin

Transcript of iOS Automation: XCUITest + Gherkin

Page 1: iOS Automation: XCUITest + Gherkin

iOS AutomationXCUITest + Gherkin

Page 2: iOS Automation: XCUITest + Gherkin

• Technical Lead iOS Engineer @ PropertyGuru• Agile, Xtreme Programming• Tests• Calabash-iOS ----> XCUITest• Demo [https://github.com/depoon/WeatherAppDemo]

Page 3: iOS Automation: XCUITest + Gherkin

Agenda

1. Introduction XCUITest2. Building a simple Test Suite3. Gherkin for XCUITest

Page 4: iOS Automation: XCUITest + Gherkin

XCUITest• Introduced in Xcode 7 in 2015• xUnit Test Cases (XCTestCase)• UITest targets cant see production codes

• Builds and tests are all executed using XCode (ObjC/Swift)

• Record functionality1. Introduction (iOS Automation Tools, XCUITest)

Page 5: iOS Automation: XCUITest + Gherkin

XCUITest - Recording

1. Introduction (iOS Automation Tools, XCUITest)

[Source] http://blog.xebia.com/automated-ui-testing-with-react-native-on-ios/

Page 6: iOS Automation: XCUITest + Gherkin

XCUITest - XCUIElement

1. Introduction (iOS Automation Tools, XCUITest)

XCUIElement //Elements are objects encapsulating the information needed to dynamically locate a user interface.element in an application. Elements are described in terms of queries [Apple Documentation - XCTest]

let app = XCUIApplication() //Object that queries views on the appapp.staticTexts //returns XCUIElementQuery “collection” representing “UILabels”app.buttons //returns XCUIElementQuery “collection” of representing “UIButtons”app.tables //returns XCUIElementQuery “collection” of representing “UITables”

app.tables.staticTexts //returns XCUIElementQuery “collection” representing “UILabels” which has superviews of type “UITable”

app.staticTexts[“Hello World”] //returns a label element with accessibilityIdentifier or text value “Hello World”

app.tables[“myTable”] //returns a table element with accessibilityIdentifier “myTable”

Page 7: iOS Automation: XCUITest + Gherkin

1. Introduction (iOS Automation Tools, XCUITest)

groups disclosureTriangles tabGroups sliders images menus

windows popUpButtons toolbars pageIndicator

s icons menuItems

sheets comboBoxes statusBars progressIndicators searchFields menuBars

drawers menuButtons tables activityIndicators scrollViews menuBarItem

s

alerts toolbarButtons tableRows segmentedCo

ntrols scrollBars maps

dialogs popovers tableColumns pickers staticTexts webViewsbuttons keyboards outlines pickerWheels textFields steppers

radioButtons keys outlineRows switches secureTextFields cells

radioGroups navigationBars browsers toggles datePickers layoutAreas

checkBoxes tabBars collectionViews links textViews otherElement

sapp.otherElements //returns [ elements ] of UIView

XCUITest - XCUIElement

Page 8: iOS Automation: XCUITest + Gherkin

XCUITest - Interactions

1. Introduction (iOS Automation Tools, XCUITest)

let app = XCUIApplication() //Object that queries views on the appapp.staticTexts[“Hello World”].exists //returns true if element exists

app.buttons[“Save”].tap() //taps the “Save” button

app.tables[“myTable”].swipeUp() //swipes up the table

app.textFields[“myField”].typeText(“John Doe”) //types value in textField

Other interactions: pinchWithScale, pressForDuration, doubleTap()

XCTAssertTrue(app.staticTexts[“Hello World”].exists) //Throws exception if label does not exists

Page 9: iOS Automation: XCUITest + Gherkin

Requirements

2. Building a simple test suite

Create a Weather App1. Given I am at the City Search Screen

When I search for a valid city (eg “London”)Then I should see a weather details page of that city

2. Given I am at the City Search ScreenWhen I search for an invalid city (eg “NotACity”)Then I should see an error message

Page 10: iOS Automation: XCUITest + Gherkin

Here’s what we built

2. Building a simple test suite

Page 11: iOS Automation: XCUITest + Gherkin

Creating a UITest Target

2. Building a simple test suite

Page 12: iOS Automation: XCUITest + Gherkin

Recording - Valid City

2. Building a simple test suite

Page 13: iOS Automation: XCUITest + Gherkin

Recording - Invalid City

2. Building a simple test suite

Page 14: iOS Automation: XCUITest + Gherkin

Generated Code - Valid City

2. Building a simple test suite

func testUserAbleToSearchForValidCity() { let app = app2 app.searchFields["Search a city"].tap() app.searchFields["Search a city"] let app2 = app app2.buttons["Search"].tap() app.searchFields["Search a city"]

let tablesQuery = app2.tables tablesQuery.staticTexts["London"].tap() tablesQuery.staticTexts["53"].tap() tablesQuery.staticTexts["Partly Cloudy"].tap() }

Page 15: iOS Automation: XCUITest + Gherkin

Generated Code - Invalid City

2. Building a simple test suite

func testUserSeesErrorMessageForInvalidCity() { let app = XCUIApplciation() app.searchFields["Search a city"].tap() app.searchFields["Search a city"] app.buttons["Search"].tap()

app.searchFields["Search a city"] let errorAlert = app.alerts["Error"]

errorAlert.staticTexts["Error"].tap()errorAlert.staticTexts[

"Unable to find any matching weather location to the query submitted!”].tap()errorAlert.collectionViews["OK"].tap()

}

Page 16: iOS Automation: XCUITest + Gherkin

2. Building a simple test suite

func testUserAbleToSearchForValidCity() { let app = XCUIApplication() let searchField = app.searchFields["Search a city"]

searchField.tap() searchField.typeText("London") app.buttons["Search"].tap() self.userWaitsToSeeText("London") self.userWaitsToSeeText("53") self.userWaitsToSeeText("Partly Cloudy”)

self.waitForExpectationsWithTimeout(5, handler: nil) }

private func userWaitsToSeeText(text: String){ self.expectationForPredicate( NSPredicate(format: "exists == 1"), evaluatedWithObject: XCUIApplication().tables.staticTexts[text], handler: nil )

// XCUIApplication().tables.staticTexts[text].exists <— boolean }

Refactored Code

Page 17: iOS Automation: XCUITest + Gherkin

2. Building a simple test suite

func testUserSeesErrorMessageForInvalidCity() { let app = XCUIApplication() let searchField = app.searchFields["Search a city”]

searchField.tap() searchField.typeText("NotACity") app.buttons["Search"].tap() self.userWaitsToSeeText("Error") self.userWaitsToSeeText(

"Unable to find any matching weather location to the query submitted!" )

self.waitForExpectationsWithTimeout(5, handler: nil)

self.userTapsOnAlertButton("OK") }

private func userTapsOnAlertButton(buttonTitle: String){ XCUIApplication().buttons[buttonTitle].tap() }

Refactored Code

Page 18: iOS Automation: XCUITest + Gherkin

2. Building a simple test suite

Scheme Management

Page 19: iOS Automation: XCUITest + Gherkin

2. Building a simple test suite

Scheme Management

Page 20: iOS Automation: XCUITest + Gherkin

Gherkin

3. Use Gherkins

Page 21: iOS Automation: XCUITest + Gherkin

(User Registration)Given I am at the user registration page

When I enter invalid email addressAnd I tap “Register“Then I should see “Invalid Email Address”

Gherkin - Example 1

3. Use Gherkins

Page 22: iOS Automation: XCUITest + Gherkin

(Shopping with existing Items in shopping cart)Given I have 1 Wallet and 1 Belt in my shopping cartAnd I am at the Shopping Item Details Page for a

Bag

When I select quantity as “1”And I tap on “Add to Shopping Cart”

Then I should be at Shopping Cart ScreenAnd I should see “3” total items in my shopping cart

Gherkin - Example 2

3. Use Gherkins

Page 23: iOS Automation: XCUITest + Gherkin

2. Building a simple test suite

Given I am at Weather Search Form Page

When I enter city search for “London”

Then I should be at Weather Details Page And I wait to see “London”And I wait to see “53”

Gherkin - Our Acceptance Tests

Page 24: iOS Automation: XCUITest + Gherkin

2. Building a simple test suite

Given I am at Weather Search Form Page

When I enter city search for “NotACity”

Then I wait to see “Error”And I wait to see “Unable to …”And I tap on alert button “OK”

Gherkin - Our Acceptance Tests

Page 25: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

• Language used in Behavioural Driven Development (BDD) to specify software requirements with examples

• Executable, facilitate collaboration with non developers

• Lets add Gherkin to our project in Xcodehttps://github.com/net-a-porter-mobile/XCTest-Gherkinpod 'XCTest-Gherkin'

Gherkin

Page 26: iOS Automation: XCUITest + Gherkin

3. Use Gherkins[Source] https://github.com/net-a-porter-mobile/XCTest-Gherkin

Gherkin

Page 27: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Given I am at Weather Search Form PageWhen I enter city search for “London”Then I should be at Weather Details Page And I wait to see “London”And I wait to see “53”

step("I (am|should be) at Weather Search Form Page”) {let weatherSearchPage =

WeatherSearchPage(self.test)}

struct WeatherSearchPage{init(testCase: XCTestCase){

testCase.expectationForPredicate(NSPredicate(format: “exists == 1”),evaluatedWithObject:

XCUIApplication().otherElements[“WeatherSearchPage”],handler: nil

)testCase.waitForExpectationsWithTimeout(5, handler: nil)

}}

Page 28: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Given I am at Weather Search Form ScreenWhen I enter city search for “London”Then I should be at Weather Details Page And I wait to see “London”And I wait to see “53”

step("I enter city search for \”(.*?)\””) { (matches: [String]) inlet weatherSearchPage = WeatherSearchPage(testCase:

self.test)weatherSearchPage.userSearchForCity(matches.first!)

}

struct WeatherSearchPage{func userSearchForCity(city: String){

let app = XCUIApplication()let searchField = app.searchFields[“Search a

city”]searchField.tap()searchField.typeText(city)app.buttons[“Search”].tap()

}}

Page 29: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Given I am at Weather Search Form PageWhen I enter city search for “London”Then I should be at Weather Details Page And I wait to see “London”And I wait to see “53”

step("I (am|should be) at Weather Details Page”) {WeatherDetailsPage(testCase: self.test)

}

struct WeatherDetailsPage{init(testCase: XCTestCase){

testCase.expectationForPredicate(NSPredicate(format: “exists == 1”),evaluatedWithObject: XCUIApplication().otherElements[“Weather

Forecast”],handler: nil

)testCase.waitForExpectationsWithTimeout(5, handler: nil)

}}

Page 30: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Given I am at Weather Search Form PageWhen I enter city search for “London”Then I should be at Weather Details Page And I wait to see “London”And I wait to see “53”

step("I wait to see \”(.*?)\””) { (matches: [String]) inself.test.expectationForPredicate(

NSPredicate(format: “exists == 1”),evaluatedWithObject:

XCUIApplication().staticTexts[matches.first!],handler: nil

)self.test.waitForExpectationsWithTimeout(5, handler: nil)

}

Page 31: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Given I am at Weather Search Form PageWhen I enter city search for “NotACity”

Then I wait to see “Error”Then I wait to see “Unable to …”Then I tap on alert button “OK”

step("I tap on alert button \”(.*?)\””) {XCUIApplication().buttons[matches.first!].t

ap()}

Page 32: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Using an additional pod to simply statements - https://github.com/joemasilotti/JAMTestHelper

Gherkin

Page 33: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Using an additional pod to simply statements - https://github.com/joemasilotti/JAMTestHelper

Gherkin

Page 34: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Gherkin

Page 35: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Gherkin

Page 36: iOS Automation: XCUITest + Gherkin

3. Use Gherkins

Gherkin

Page 37: iOS Automation: XCUITest + Gherkin

Gherkin

3. Use Gherkins

Page 38: iOS Automation: XCUITest + Gherkin

Gherkin

3. Use Gherkins

Page 39: iOS Automation: XCUITest + Gherkin

Gherkin - Using Feature File

3. Use Gherkins

Page 40: iOS Automation: XCUITest + Gherkin

Why should I use Gherkin with XCUITest?

3. Use Gherkins

• Acceptance Test Driven Development• Cross platform testing is still possible without need for

3rd party tools• Objective C + Swift