In the last post, we have touched upon some best practices of organizing XCUIElements for scalable UI tests with Swift enumeration. While architecting iOS app testing with XCUITests for iOS devices with different screen sizes, we should also consider the scalability and maintainability of our code. We have to make sure XCUITest tests would run flawlessly on all iOS variants without causing a lot of code duplication by architecting XCUITest tests in a proper manner. In this post, we will see some best practices of architecting XCUITests for different screen sizes.

Common Mistakes

One of the most common mistakes that iOS automation engineers make while architecting XCUITest for iPhones and iPads is creating two separate test suites for each screen sizes. There are two separate Xcode schemes executing the tests on iPads and iPhones. There is also a conditional execution all over the tests, which makes its brittle to manage test suites. This approach will create a lot of code duplication across multiple UI test targets.

Another one is that iOS automation engineers tend to define iPhone and iPad specific XCUIElelemts if elements are located at the different position in the UIView. e.g. iPadEnterButton and iPhoneEnterButton. This approach will cause lots of XCUIElements defined for the same element located differently for iPhone and iPad. But there’s a way to eliminate the need of code duplication. Before we jump into the solution, we can see some of the device-specific APIs provided by Apple.

UIDevice

Apple has provided the UIDevice API to get a representation of the current device and the XCUIDevice class to simulate physical buttons and device orientations. These two classes make architecting tests on iPhones and iPads so easy if we have organized the XCUIElements properly. By using the UIDevice API, we can get the current device:

if UIDevice.current.userInterfaceIdiom == .pad {
// Do iPad Stuff
}

With XCUIDevice, we can set the device orientation to landscape or portrait using the following code:

XCUIDevice.shared().orientation = .landscapeRight

With the help of these two APIs, it would be super easy to set our XCUITests on both iPhones and iPads using the conditional return of the XCUIElement.

Refactor Swift Enum for iPad Elements

In our XCUITest101 app, imagine that we have an enter button in the main view while in the iPad it’s in the tab bar. The XCUIElement for the enter button in the iPhone is

XCUIApplication().buttons["enter"]

While the XCUIElement for the enter button in the iPad is

XCUIApplication().tabBars["iPadTabBar"].buttons["enter"]

We already have an enum defined in the WelcomeScreen.swift file which returns UI element for the enter button. The enum mentioned in that file will work perfectly for the iPhones as the enter button can be found in the main view. However, if we have a situation with an iPad design, enter button is in the Tab bar. The approach mentioned in the enum will not work for iPads. However, by using UIDevice, we can conditionally return XCUIElements from the above enum if the device is an iPad. We can easily refactor that enum to conditionally return the UI elements for both iPhone and iPad as shown below.

The full source code of the refactored enum in the WelcomeScren.swift can be found here. Now that enum will return an enter buttons from the tab bars for iPad and from the main view for iPhones. We don’t have to touch our actual test implementation from which these XCUIElements will be accessed. With this conditional login, we can achieve the following benefits:

We can write a single XCUITest test which will work on both iPhones and iPads.

There is no need to create separate test suites or define separate XCUIElements for iPhones and iPads.

There is no need to write separate step definitions for iPhones and iPads.

No need to create separate schemes for running XCUITests on iPhones and iPads.

This approach will avoid a lot of code duplication.

With this simple trick, you can refactor all the UI elements in your iOS app and make the tests scalable for both iPhone and iPad design. Now your XCUITest tests are suitable to run on both iPhone and iPad devices. If you want to try it out on some free iOS devices in a device cloud, you can check out the mobile device cloud Bitbar Testing has to offer.

Did you know Bitbar offers iOS trial devices for automated and manual testing?

Conclusion

With the combination of XCUITest, Swift enumerations and the UIDevice API from Apple, we can achieve UI test automation on iPhone and iPad devices without repeating code. There is no need to create separate schemes or add conditions everywhere in the test code for iPad scenarios. This approach will make your iOS app testing much smoother, scalable and maintainable. What is your approach of architecting XCUIElements on iPhone and iPads? Leave your comments below.