Download - iOS Automation: XCUITest + Gherkin
![Page 1: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/1.jpg)
iOS AutomationXCUITest + Gherkin
![Page 2: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/2.jpg)
• Technical Lead iOS Engineer @ PropertyGuru• Agile, Xtreme Programming• Tests• Calabash-iOS ----> XCUITest• Demo [https://github.com/depoon/WeatherAppDemo]
![Page 3: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/3.jpg)
Agenda
1. Introduction XCUITest2. Building a simple Test Suite3. Gherkin for XCUITest
![Page 4: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/4.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/5.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/6.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/7.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/8.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/9.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/10.jpg)
Here’s what we built
2. Building a simple test suite
![Page 11: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/11.jpg)
Creating a UITest Target
2. Building a simple test suite
![Page 12: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/12.jpg)
Recording - Valid City
2. Building a simple test suite
![Page 13: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/13.jpg)
Recording - Invalid City
2. Building a simple test suite
![Page 14: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/14.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/15.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/16.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/17.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/18.jpg)
2. Building a simple test suite
Scheme Management
![Page 19: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/19.jpg)
2. Building a simple test suite
Scheme Management
![Page 20: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/20.jpg)
Gherkin
3. Use Gherkins
![Page 21: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/21.jpg)
(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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/22.jpg)
(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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/23.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/24.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/25.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/26.jpg)
3. Use Gherkins[Source] https://github.com/net-a-porter-mobile/XCTest-Gherkin
Gherkin
![Page 27: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/27.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/28.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/29.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/30.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/31.jpg)
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](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/32.jpg)
3. Use Gherkins
Using an additional pod to simply statements - https://github.com/joemasilotti/JAMTestHelper
Gherkin
![Page 33: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/33.jpg)
3. Use Gherkins
Using an additional pod to simply statements - https://github.com/joemasilotti/JAMTestHelper
Gherkin
![Page 34: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/34.jpg)
3. Use Gherkins
Gherkin
![Page 35: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/35.jpg)
3. Use Gherkins
Gherkin
![Page 36: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/36.jpg)
3. Use Gherkins
Gherkin
![Page 37: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/37.jpg)
Gherkin
3. Use Gherkins
![Page 38: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/38.jpg)
Gherkin
3. Use Gherkins
![Page 39: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/39.jpg)
Gherkin - Using Feature File
3. Use Gherkins
![Page 40: iOS Automation: XCUITest + Gherkin](https://reader031.vdocuments.us/reader031/viewer/2022012306/587375711a28ab3c1a8b63ad/html5/thumbnails/40.jpg)
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