wegenmic wegenmic - 4 months ago 22
iOS Question

Xcode UI Testing [xcode7-beta6] - Asserting actual label values when using accessibility labels

The question is actually really simple:

Is there a way to assert the displayed value from a specific label (e.g. UILabel) when using an accessibility label on this object?

As far as I see it, all the assertions (e.g. XCTAssertEquals) made in the examples, be it from a WWDC Talk or Blogposts, are only checking if an element exists for a query like

XCTAssertEquals(app.staticTexts["myValue"].exists, true)
or if the number of cells in a table is correct
XCTAssertEquals(app.tables.cells.count, 5)
. So, when avoiding accessibility labels it's possible to check if an object has a certain value displayed, but not which object / element.
And when using accessibility labels, it robs me of the opportunity to query against the displayed values, because
app.staticTexts["myValue"]
will now fail to deliver a result but
app.staticTexts["myAccessibilityLabel"]
will hit.

Assuming I want to test my "Add new Cell to Table" functionality, I can test that there is really a new cell added to the list, but I have no idea if the new cell is added at the top or the bottom of the list or somewhere in between.

For me, an easy way to check if a specific element has a certain value should be a no-brainer when it comes to UI Testing.

It is possible that due to the missing documentation I might overlook the obvious. If so, just tell me.

Answer

I think you are asking a few different things, so I will try to answer each question individually.

  1. Is there a way to assert the displayed value from a specific label (e.g. UILabel) when using an accessibility label on this object?

In short, no. UI Testing works by hooking into accessibility APIs, so you are limited to querying for objects based on that. You can, however, check the -value property of certain elements, such as controls. This is used to test if a switch is on or off. Note that these boil to down using accessibility APIs as well, just a different method (-accessibilityValue over -accessibilityIdentifier and -accessibilityLabel).

  1. ...but I have no idea if the new cell is added at the top or the bottom of the list or somewhere in between.

To interrogate an XCUIElement for its frame you can use the new XCUIElementAttributes protocol which exposes -frame. For example:

let app = XCUIApplication()
app.launch()

app.buttons["Add New Cell to Table"].tap()

let lastCell = app.cells["Last Cell"]
let newCell = app.cells["New Cell"]

XCTAssert(newCell.exists)
XCTAssert(newCell.frame.minY > lastCell.frame.maxY)
  1. For me, an easy way to check if a specific element has a certain value should be a no-brainer when it comes to UI Testing.

If you think of everything in terms of accessibility this becomes a non-issue. UI Testing can only interact with your elements via accessibility APIs, so you must implement them. You also get the added benefit of making your app more accessible to user's with those settings enabled.

Try setting both the -accessibilityLabel or -accessibilityIdentifier for the cell to the displayed text. UI Testing can be finicky as to which one it uses.

  1. It is possible that due to the missing documentation I might overlook the obvious. If so, just tell me.

XCTest and UI Testing don't have any official documentation. So I've gone and extracted my own from the header files exposed in the framework. Note than even though they were pulled from source, they are unofficial.

XCTest / UI Testing Documentation