Libor Zapletal
Libor Zapletal

Reputation: 14092

UI testing - how to check that I am in right controller?

I have button in my controller and after click on button I made request and check the result. If it is error than I show alert else I perform segue to another controller. I would like to have UI tests for this. This is how end of my test methods looks like:

func testExample() {
  ...
  elementsQuery.buttons["CreateAccount"].tap()

  XCTAssertEqual(app.navigationBars.element.identifier, "ProgrammeViewController")
}

I get break at last line. I think I didn't set it right. But I am not sure how to set it. I have title in that controller but I change it for each language. So I want to use accessibilityLabel. I tried:

self.navigationController?.navigationBar.accessibilityLabel = "ProgrammeViewController"
self.navigationItem.accessibilityLabel = "ProgrammeViewController"

But it didn't help. So what's the right way to do this? And should I set accessibilityLabel in viewDidLoad or viewWillAppear? I think if I want to use this for multiple controllers then the viewWillAppear would be better right? Thanks for help

Upvotes: 3

Views: 1750

Answers (2)

anka
anka

Reputation: 3857

This is only an extension to the answer already given. Like @ishaq already said, the storyboard does not provide Accessibility attributes for every component. But you can use User Defined Runtime Attributes to set accessibilityIdentifier easily within storyboards too.

enter image description here

Upvotes: 0

ishaq
ishaq

Reputation: 1841

Short Answer:

Set accessibilityIdentifier instead of accessibilityLabel

self.navigationController?.navigationBar.accessibilityIdentifier = "ProgrammeViewController"

Long Answer:

From UIAccessibilityIdentification protocol:

The UIAccessibilityIdentification protocol is used to associate a unique identifier with elements in your user interface. You can use the identifiers you define in UI Automation scripts ...

This document is a bit outdated since it talks about UI Automation (Apple's UI Testing framework before Xcode 7). The point is that, for UI Testing, it recommends using the property (accessibilityIdentifier) defined in this protocol.

And, from UIAccessibility protocol on accessibilityLabel:

If an accessibility element does not display a descriptive label, set this property to supply a short, localized label that succinctly identifies the element. For example, a “Play music” button might display an icon that shows sighted users what it does. To be accessible, however, the button should have the accessibility label “Play” or “Play music” so that an assistive application can provide this information to users with disabilities.

So accessibilityLabel is to help disabled users.

Discussion: While you can use both accessibilityLabel and accessibilityIdentifier in UITesting code because, after all, UI Testing is like a User going through our application, If the soul purpose is to identify an element, Do not use label.

Always use accessibilityIdentifier to identify an element

accessibilityLabel is not to identify elements. It is to help people with disabilities. Testing that it is set correctly is a valid test. For example, one could write a test for Stop icon that checks that accessibilityLabel for it is indeed "Stop" (or a localized variant) instead of some other string.

Ideally, accessibilityLabel should change depending on user's locale, "Stop" should become "رکیے" in Urdu. However, accessibilityIdentifier should stay the same. The user never sees it. It is there for you, the programmer, to identify elements in UI Testing. accessibilityIdentifier = "MusicPlayerController" will stay "MusicPlayerController" regardless of the user's locale.

Where to set accessibilityIdentifier

It does not matter whether you set it in viewWillAppear or viewDidLoad as long as it is set by the time UI gets displayed. I tend to set these in Storyboard (or .Xib). Not all controls expose this field in Storyboard though e.g. UITableView, for these I set it in viewDidLoad.

Upvotes: 2

Related Questions