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

15.2k Views Asked by At

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.

4

There are 4 best solutions below

4
On BEST ANSWER

Be sure to set the .accessibilityValue property of the UILabel whenever you set its .text value. Then in UITest, you can test the accessibility value like this:

    let labelElement = app.staticTexts["myLabel"]
    ...
    XCTAssertEqual(labelElement.value as! String, "the expected text")
0
On

From the apple forums it looks like it is possible to get the value of the label:

The only way I've found is to not set an Accessibility Label, but use identifier instead. Then XCUIElement.label will change to match the current text of the label.

However there is a gotcha: if you have previously set Accessibility Label in XC, and remove it, an entry setting the label to "" remains in the storyboard. In this case, not only will calling .label will return "", but you won't be able to query for the label by it's text!

The only thing you can do is delete and re-add the label, or manually edit the xml.

lastobelus - https://forums.developer.apple.com/thread/10428

2
On

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

0
On

What works for me is to set the accessibility identifier of the UILabel to let's say MyLabel.

func myLabelText() -> String {
  let myLabelUIElement: XCUIElement = self.application.staticTexts["MyLabel"]

  return myLabelUIElement.label
}

Tested with Xcode 8 and iOS 10