UI Test Changes to SwiftUI List and Stepper in iOS 16

Since SwiftUI came out, the extremely useful List control, for creating scrolling, single column, table-style views has been backed under the hood by UITableView. While this probably made it simpler and faster to release the feature, it also had the side effect of tying SwiftUI implementation to a lot of legacy code.

With iOS 16, Apple released this small blurb in the release notes:

  • The implementation of List no longer uses UITableView. (81571203)

Other issues aside, this is an awesome change as it moves everyone closer to that glorious day when Swift can shed the baggage of Objective-C (I can dream anyways 😀).

There is one minor side effect to note from this change that impacts UI tests though. Previously one would have written code to access elements in a SwiftUI List with something like:

let app = XCUIApplication()
// Do something with a button in a List
app.tables.cells.buttons["Tap Me"].firstMatch.tap()

Now since List is no longer backed by legacy code, XCUITest no longer recognizes any tables or cells in the above code. You simply have to use otherElements to work around the issue for now.

let app = XCUIApplication()
// Do something with a button in a List
app.otherElements.buttons["Tap Me"].firstMatch.tap()

This change may cause some issues of course; but it’s pretty typical when new iOS versions come out to have some undocumented (or sparsely documented) changes around XCUITest behavior.

For example the SwiftUI Stepper finally exposes the increment and decrement buttons to XCUITest. With previous versions of iOS and SwiftUI, calling tap() on the stepper in an XCUITest would increment the stepper and nothing else. But steppers need to go down too, right? Without a lot of extra work and coordinate tapping to hit the decrement button, that is.

Now the buttons within the Stepper are available as buttons["Increment"] and buttons["Decrement"] and our tests can do so much more!

let app = XCUIApplication()
// Previously could only increment (+1) stepper
app.steppers.firstMatch.tap() 
// Now we can actually go up AND down
app.steppers.firstMatch.buttons["Increment"].firstMatch.tap()
app.steppers.firstMatch.buttons["Decrement"].firstMatch.tap()

It definitely seems like the XCTest framework in regards to SwiftUI is still very much in flux but slowly getting better. I’ll be filing a feedback so that we can maybe break out some of these issues with otherElements (which tends to be a grab bag of unclassified items).

Thanks for reading! Please feel free to comment, share, like, etc. and let me know what you think.

Published by Mark Thormann

As a software developer and architect, I enjoy using technology to craft solutions to business problems, focusing on all aspects of native iOS and Android mobile development as well as application architecture, automation. and many other areas of expertise. I'm currently working at one of the leading career-related companies in the United States, using mobile applications to help connect job seekers in the technology industry to the employment which they need.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: