Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

iOS Automation: XCUITest + Gherkin

28th July 2016 iOS Dev Scout Meetup @ Propertyguru
Presentation on
- XCUITest: how to easily setup and run XCUITests
- Gherkin: how to setup Gherkin for your XCUITests

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to comment

iOS Automation: XCUITest + Gherkin

  1. 1. iOS Automation XCUITest + Gherkin
  2. 2. • Technical Lead iOS Engineer @ PropertyGuru • Agile, Xtreme Programming • Tests • Calabash-iOS ----> XCUITest • Demo [https://github.com/depoon/WeatherAppDemo]
  3. 3. Agenda 1. Introduction XCUITest 2. Building a simple Test Suite 3. Gherkin for XCUITest
  4. 4. 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 functionality 1. Introduction (iOS Automation Tools, XCUITest)
  5. 5. XCUITest - Recording 1. Introduction (iOS Automation Tools, XCUITest) [Source] http://blog.xebia.com/automated-ui-testing-with-react-native-on-ios/
  6. 6. 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 app app.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”
  7. 7. 1. Introduction (iOS Automation Tools, XCUITest) groups disclosureTrian gles tabGroups sliders images menus windows popUpButtons toolbars pageIndicators icons menuItems sheets comboBoxes statusBars progressIndicat ors searchFields menuBars drawers menuButtons tables activityIndicator s scrollViews menuBarItems alerts toolbarButtons tableRows segmentedCon trols scrollBars maps dialogs popovers tableColumns pickers staticTexts webViews buttons keyboards outlines pickerWheels textFields steppers radioButtons keys outlineRows switches secureTextFiel ds cells radioGroups navigationBars browsers toggles datePickers layoutAreas checkBoxes tabBars collectionViews links textViews otherElements app.otherElements //returns [ elements ] of UIView XCUITest - XCUIElement
  8. 8. XCUITest - Interactions 1. Introduction (iOS Automation Tools, XCUITest) let app = XCUIApplication() //Object that queries views on the app app.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
  9. 9. Requirements 2. Building a simple test suite Create a Weather App 1. 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 Screen When I search for an invalid city (eg “NotACity”) Then I should see an error message
  10. 10. Here’s what we built 2. Building a simple test suite
  11. 11. Creating a UITest Target 2. Building a simple test suite
  12. 12. Recording - Valid City 2. Building a simple test suite
  13. 13. Recording - Invalid City 2. Building a simple test suite
  14. 14. 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() }
  15. 15. 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() }
  16. 16. 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
  17. 17. 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
  18. 18. 2. Building a simple test suite Scheme Management
  19. 19. 2. Building a simple test suite Scheme Management
  20. 20. Gherkin 3. Use Gherkins
  21. 21. (User Registration) Given I am at the user registration page When I enter invalid email address And I tap “Register“ Then I should see “Invalid Email Address” Gherkin - Example 1 3. Use Gherkins
  22. 22. (Shopping with existing Items in shopping cart) Given I have 1 Wallet and 1 Belt in my shopping cart And 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 Screen And I should see “3” total items in my shopping cart Gherkin - Example 2 3. Use Gherkins
  23. 23. 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
  24. 24. 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
  25. 25. 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 Xcode https://github.com/net-a-porter-mobile/XCTest-Gherkin pod 'XCTest-Gherkin' Gherkin
  26. 26. 3. Use Gherkins[Source] https://github.com/net-a-porter-mobile/XCTest-Gherkin Gherkin
  27. 27. 3. Use Gherkins 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” 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) } }
  28. 28. 3. Use Gherkins Given I am at Weather Search Form Screen 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” step("I enter city search for ”(.*?)””) { (matches: [String]) in let 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() } }
  29. 29. 3. Use Gherkins 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” 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) } }
  30. 30. 3. Use Gherkins 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” step("I wait to see ”(.*?)””) { (matches: [String]) in self.test.expectationForPredicate( NSPredicate(format: “exists == 1”), evaluatedWithObject: XCUIApplication().staticTexts[matches.first!], handler: nil ) self.test.waitForExpectationsWithTimeout(5, handler: nil) }
  31. 31. 3. Use Gherkins Given I am at Weather Search Form Page When 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!].tap() }
  32. 32. 3. Use Gherkins Using an additional pod to simply statements - https://github.com/joemasilotti/JAMTestHelper Gherkin
  33. 33. 3. Use Gherkins Using an additional pod to simply statements - https://github.com/joemasilotti/JAMTestHelper Gherkin
  34. 34. 3. Use Gherkins Gherkin
  35. 35. 3. Use Gherkins Gherkin
  36. 36. 3. Use Gherkins Gherkin
  37. 37. Gherkin 3. Use Gherkins
  38. 38. Gherkin 3. Use Gherkins
  39. 39. Gherkin - Using Feature File 3. Use Gherkins
  40. 40. 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
  41. 41. Questions? kenneth@propertyguru.com.sg de_poon@hotmail.com

    Be the first to comment

    Login to see the comments

  • leongkuilim

    Aug. 3, 2016
  • PavelNikitinsky

    Oct. 12, 2016
  • chinglongsu

    Feb. 23, 2017
  • JessBsoulGarca

    Jun. 16, 2017
  • LeanidTryfanau

    Sep. 15, 2017
  • AnnaPuskarjova

    Mar. 26, 2018

28th July 2016 iOS Dev Scout Meetup @ Propertyguru Presentation on - XCUITest: how to easily setup and run XCUITests - Gherkin: how to setup Gherkin for your XCUITests

Views

Total views

6,012

On Slideshare

0

From embeds

0

Number of embeds

54

Actions

Downloads

59

Shares

0

Comments

0

Likes

6

×