Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
UI Testing in Xcode

Wil Turner, Brook Callhan: Speakers

##3 Main components/concepts that enable UI Testing:##

  • UITesting
    • Find and interact w/ UI elements
    • Validate UI properties and state
  • UIrecording
    • Updated test reports to include UI testing data
    • UI testing is enabled by XCTest and UI Accesibility
    • CI via xcode server and xcodebuild
  • Accesibility
    • Integrated with UIKit and App Kit
    • APIs


  • Depends on new OS feature (iOS 9 +)
  • iOS devices must be enabled for development and connected to a trusted host

##Getting Started##

  • New XCode target type (UI test target type)

    • Support special requirements
      • Execute in a separate process
      • Permissin to use accesiblity
    • New xcode target templates
      • Specifies the app that the tester target can interact with. (So it's all application level, not view controller level)
        • Does this mean that all tests have to begin by booting the app? I.e, we can't skip to a view that's 4 levels in
  • New APIs for creating the tests

    • Three new classes: XCUIApplication, XCUIElement XCUIElementQuery
    • XCUIApplication
     let app = XCUIApplication()
    • XCUIElement
      • Proxy for elements in application
      • Types: button cell, window, etc.
      • Identifiers: accsiblity label, title label, etc.
      • You find elements by a combination of type + identifier
      • Elements MUST be unique: every erlement is backed by a query; query must resolve to exactly one match
        • No matches or multiple matches cause test failure
        • One exception to previous rule: exists property.
      • Event synthesis:
        • This is how we simulate user interaction on elements
        • APIs are platform-specific (button.tap() for iOS, for OSX)
    • XCUIEleemntQuery
      • Resolves to collections of accesible elements
        • count = number of matches for a query
        • Use subscript or elementAtIndex() to access elements within a query
      • Queries work by relationships and filtering (duh)
        • Descendants = direct descendants of a view
        • Childrent = direct and indirect descendants of a view
        • `Containtment ???
        • Filters can accept predicates for value, partial matching, etc.
      • 3 Queries which combine relationships + filters
        • descendantsMatchingType()
          • there's convenience apis!!! e.g 'table.descendantsMatchingType(.Cell [??]) -> table.cells
            • Not sure if verbose version was .Cell or .UITableViewCell
        • containingType()
          • Find elements by describing their descendants
        • childrenMatchingType()
      • Queries can be chained
      • Getting elements from queries
        • Can use subscripts with identifier table.statitcTexts["Groceries"]
        • Index: table.staticTexts.elementAtIndex(0)
        • Single child: table.staticTexts.element
      • Queries are evaluated on demand, re-evaluated when UIChanges
        • If you evaluate a query (i.e count # of cells), do something that would change the result of that query (i.e - add a row), then re-evaluate that query - it will have a different result

UI Recording

  • Interacts with app
  • Recording generates the code to repeat the tests

##Demo (basic)

  • downloadable from apple developer website
  • By interacting with elements, we get implicit validation that the elements exist. We don't get validation about the state of the application (ie, we can tap an element, but we don't get any validation that it changes color or gets disabled or whatever) - we need to manually add explict assertions

##Accesibility and UI Testing##

  • By making an app testable, you're automatically making it more accesible
  • Debuging tips
    • Not accesible:
  • Improve accesiblity data via IB inspector or via UIAccessibility

##Demo (advanced)

  • Tests fail if you have multiple matches for a query
    • We know that because we saw the tests run. What if they fail when you're not running them?
    • Looking at the test reporter. It's got english language descriptions!!!
    • It shows which step the test failed at
    • Shows the whole UI View hierarchy in the failure log!!
    • Re-run the test, pause it, get a unique reference to the element that's got the same identifier
  • Deleting all the cells
    • Create a query using a predicate to find the delete button for each cell
  • Tapping on some UI Elements
    • The wrong elements get detected if the UIElement that you're actually touch is not accessible.
    • Some debugger - if you put yuor cursor over the screen, it'll highlight the accessibility element that it thinks you're hovering over.
      • If it's not the element you expect: your element is not accessible

##Test reports

  • UITesting APIs have several steps (nternal)
  • QuickLooks capture view at key steps!!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.