ios automation: xcuitest + gherkin

Post on 16-Apr-2017

1.774 Views

Category:

Software

12 Downloads

Preview:

Click to see full reader

TRANSCRIPT

iOS AutomationXCUITest + Gherkin

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

Agenda

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

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)

XCUITest - Recording

1. Introduction (iOS Automation Tools, XCUITest)

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

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”

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

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

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

Here’s what we built

2. Building a simple test suite

Creating a UITest Target

2. Building a simple test suite

Recording - Valid City

2. Building a simple test suite

Recording - Invalid City

2. Building a simple test suite

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() }

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()

}

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

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

2. Building a simple test suite

Scheme Management

2. Building a simple test suite

Scheme Management

Gherkin

3. Use Gherkins

(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

(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

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

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

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

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

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)

}}

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()

}}

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)

}}

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)

}

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()}

3. Use Gherkins

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

Gherkin

3. Use Gherkins

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

Gherkin

3. Use Gherkins

Gherkin

3. Use Gherkins

Gherkin

3. Use Gherkins

Gherkin

Gherkin

3. Use Gherkins

Gherkin

3. Use Gherkins

Gherkin - Using Feature File

3. Use Gherkins

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

Questions?

kenneth@propertyguru.com.sgde_poon@hotmail.com

top related