Mobile testing: An introduction to XCUITest
How to find the element in the iOS app: Record your test, accessibility inspector and po debug
I will write some articles about how to test iOS apps. The first article is a basic introduction to the different types of mobile apps and how you can locate the elements of your iOS apps.
Types of Mobile Apps
There are different types of mobile apps.
Native Apps: developed on the specific phone platform using the native language of the phone
Kotlin/Java for Android
Swift/Objective C for iOS
Hybrid Apps: Combine elements of native and web apps. They are built-in web apps that run in one container and can be distributed in app stores. Some frameworks are:
Progressive Web Apps: Enhanced web apps that behave like native apps. Have some options to work offline, send push notifications, and can be installed from the browser. You can create these apps with
Cross Platform: Some development frameworks allow you to create your apps in iOS and Android with one common language
Options to test mobile apps
To test your mobile application, you can use
Appium: An open source project to test your apps with some configuration capabilities, you can change between Android and iOS apps.
Detox: Designed to test React Native apps
Maestro: A platform to test web and mobile apps (React Native, Flutter, MAUI, iOs, Android, Native script, and Cordova)
Espresso: To test Android apps
XCUITest: framework developed and presented by Apple in 2015 to automate the tests of your iOS apps.
If the company has native apps with developers focused on the iOS app and another team focused on the Android app, you can do the same for testing and add a test with XCUITest for the iOS app and Espresso for the Android app.
Types of iOS Apps
The way iOS apps are developed has changed with time.
Objective C: It’s a superset of C and was the first language and is the oldest.
Swift: Another language introduced by Apple in 2014, it’s easier than objective C. The UI uses storyboards and includes some rules by code or with the XCode to make your apps responsive
SwiftUI: Introduced in 2019, it consists of a declarative UI framework that automatically adjusts the components to be displayed in different screen sizes and orientations.
Accessibility Identifiers
To find the elements, developers can add accessibility identifiers. For example, you can add a label for each dog breed image on the previous app.
The accessibility Label is how the Screen Reader will read the image's description.
Image(dogBreedData.imageName)
.resizable()
.scaledToFill()
.clipShape(RoundedCorner(radius: 20, corners: [.topLeft, .topRight]))
.accessibilityIdentifier("\(dogBreedData.breed) image")
.accessibilityLabel("\(dogBreedData.breed)")
How to create tests with XCUITest
Add the Test UI Project
Select File > New > Target
Select UI Testing Bundle
Click Next
On
Language select Swift
Project select the code for the app
Click Finish
This will create a new project with some tests by default.
Basic code examples
To launch the application, you need this code:
let app = XCUIApplication()
app.launch()
You can access the components with an array, for example:
app.navigationBars["name"].buttons["text_or_name"].tap
Select the first element on a collection view
let collectionView = app.collectionViews["collectionViewName"]
let firstCell = collectionView.cells.element(boundBy: 0)
You can also search by predicate, for example, the buttons with the label breed
let containsBreed = NSPredicate(format: "label CONTAINS[c] %@", "breed")
let breedButtons = app.buttons.matching(containsBreed)
You can also extensions to wait before tapping an element
extension XCUIElement {
/// Waits for element and taps it when available
func waitAndTap(timeout: TimeInterval = 5) -> Bool {
guard self.waitForExistence(timeout: timeout) else { return false }
self.tap()
return true
}
}
app.buttons["text_or_name"].waitAndTap(timeout: 10)
You can add different types of asserts:
// 1. Basic Existence Assertions
let collectionView = app.collectionViews["dog_breeds_title"]
XCTAssertTrue(collectionView.exists, "Collection view should exist")
// 2. Count Assertions
let breedButtons = collectionView.buttons
XCTAssertGreaterThan(breedButtons.count, 0, "Should have at least one breed button")
// 3. Element State Assertions
let boykinButton = breedButtons["breed_row_boykin_spaniel"]
XCTAssertTrue(boykinButton.isEnabled, "Boykin Spaniel button should be enabled")
// 4. Text Assertions
XCTAssertEqual(backButton.label, "Dog Breeds", "Back button should have correct label")
// 5. Boolean Assertions
XCTAssertFalse(boykinButton.isSelected, "Button should not be selected")
// 6. Validate that contains a value
XCTAssertNotNil(navigationBar, "Navigation bar should not be nil")
For the different types of iOS apps, you use the same XCUITest. You can find your elements with any of these options:
Test recording
You can record your steps, and XCode will generate the code.
The cursor needs to be in a function that starts with test; if it is decorated with @MainActor, the button to record is disabled.
Accessibility Inspector
You can select the elements and get the info about that element of any app.
You can open the accessibility inspector from Xcode > Open Developer Tool > Accessibility Inspector and select any of the app's elements running on a simulator.
Debugger
You can print the current components of the app when you add a breakpoint to your test.
Resources to learn
There are a few resources to learn XCUITest, but I finished these:
Introduction to iOS Test Automation with XCUITest: An elementary course with some basic concepts for testing apps.
iOS SDET by Engenious University: 2 courses to learn how to create tests with a restaurant iOS app
CURSO TESTING en SWIFT y SWIFTUI sobre Unit Tests, Integration Tests, Snapshot Tests y UITests Xcode: Course in Spanish with a basic introduction to different types of testing.
Testing Swift: Book that explains unit tests, UI tests, and TDD.
The unit testing in Swift was changed last year (2024), and maybe the UI Tests will also change.
It’s essential that you can test with real apps. If you need some apps to practice testing with more realistic apps, you can check the following list: Open Source iOS Apps.
You can also check my sample with 1 example of mobile testing with the Avocado App.
You can also check the Dog Breed App, where I added a basic unit test and one basic UI test without any assertions.
Thank you for reading, and feel free to suggest a topic for a new article and share if you think it is useful. Enjoy testing!!