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

4

20

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.

Wong answered 31/8, 2015 at 15:27 Comment(0)
M
24

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")
Macmahon answered 23/7, 2016 at 9:28 Comment(4)
this approach will work for objc also but you have to use XCTAssertEqualObjects((NSString *)labelElement.value, @"the expected text", @"These strings should be equal!");Arlinda
You can also set the accessibilityIdentifier either in Storyboard or programmatically and get the XCUIElement with that.Red
Using the accessibilityIdentifier would be better if you're actually using the VoiceOver function, because I believe the Accessibility Label is localized and so could change based on language, whereas the identifier wouldn't.Red
What , if we have to find the static text based on tag rather than label text or accessibility identifier ???Emilie
J
11

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

Jackofalltrades answered 1/9, 2015 at 13:39 Comment(2)
Thanks a lot @joe. But you do agree that it's strange that you can check the value of a checkbox (active or not), but not the value (the displayed text) of a UILabel. Right? For me this means I cannot use UI Testing for functional test cases, because most of those I encounter contain requirements like if you enter 'abc' in text field 'a' and hit button 'b', then the label 'c' should display 'xyz'.Wong
@Wong Suggest thinking slightly differently. Remember a UIElement isn't an actual UI Object, it's a search path to a UI Object. You simply have to create another "search path". app.staticTexts["New Label Text"]. Threw me for a loop at the beginning... "value" isn't particular useful.Assagai
T
9

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

Teplitz answered 28/7, 2016 at 21:50 Comment(0)
V
3

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

Vetavetch answered 30/11, 2015 at 14:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.