DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Modern Test Automation With AI (LLM) and Playwright MCP
  • AI-Driven Test Automation Techniques for Multimodal Systems
  • Debugging With Confidence in the Age of Observability-First Systems
  • Accelerating Debugging in Integration Testing: An Efficient Search-Based Workflow for Impact Localization

Trending

  • The Smart Way to Talk to Your Database: Why Hybrid API + NL2SQL Wins
  • Can You Run a MariaDB Cluster on a $150 Kubernetes Lab? I Gave It a Shot
  • AI Speaks for the World... But Whose Humanity Does It Learn From?
  • Introducing Graph Concepts in Java With Eclipse JNoSQL
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Writing DRY XCUITest Tests With Base Classes

Writing DRY XCUITest Tests With Base Classes

Learn how to make XCUITest tests more readable, scalable, maintainable, and reusable.

By 
Shashikant Jagtap user avatar
Shashikant Jagtap
·
Oct. 16, 18 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
8.3K Views

Join the DZone community and get the full member experience.

Join For Free

In our previous post on setting up the XCUITest framework, we got up and running with a sample XCUITest with Xcode 10. Apple's XCUITest framework gives us the ability to record basic user journeys to get started with XCUITest, but the recorded tests are not scalable and reusable. We have to make an effort to make the XCUITest more readable, scalable, maintainable, and reusable.

As per the approach mentioned in the previous post, we are able to add more UI tests but there will be a lot of duplication of code which could make our UI tests hard to maintain and fix. Writing automated tests is pretty easy, but writing solid tests is harder as the size and complexity of the project grow incrementally. There are various testing approaches and test patterns available to make tests scalable. In this post, we will cover how to make XCUITest tests robust by abstracting the common Swift code in the base class.

Create a Base Class for XCUITest Tests

Most testing frameworks use the concept of the base class to abstract the common functionality of test classes. In short, the base class is the superclass which offers a common functionality to test classes. In our XCUITest101 Xcode project, we have a UI test class XCUITest101UITests.swift with all the methods like the setup, teardown, and test methods in a single class. If we want to add new XCUITest tests, then we have to repeat the setup and teardown methods per test class. Clearly, this will create a lot of duplicate code in our iOS project, which makes it hard to maintain later on and might prolong your test execution on a mobile device cloud. In order to avoid this, let's create a base UI Test class from Xcode -> File -> New -> File -> Swift File -> Next and name the file XCUITestBase and make sure we have selected the target XCUITest101UITest for this file.

This will create a new file XCUITestBase.swift under the UI test target where we can abstract the common code.

Abstract the Common Testing Workflow

Now that we have created the base class for XCUITest, we can think about the common and repetitive code that we can include in the base class. Looking at our existing test class XCUITest101UITests, we can abstract following things in the base class:

  • Setup and Teardown methods
  • The instance of XCUIApplication() that might be needed in later tests

These two are the very obvious things that we must abstract to be reused later. As the project and test suites grow, however, there might be the need to abstract more common workflows in the future. While writing XCUITest tests, it's essential to configure our app in a state where we can run tests reliably. Apple has provided the mechanisms of launch arguments and launch environments to be passed to each test class. It makes sense to configure an ability to add launch arguments from the base class. One good example would be when we want to start each test from a clean state using the launch argument

XCUIApplication().launchArguments = ["-StartFromCleanState", "YES"]

This is an example of a launch argument, but you can pass any arguments or environment created by your iOS developers. We can configure that in the base class, and we will also extend the base class to the XCTestCase class. In the end, our XCUITestBase class looks like this:

Now that we have created our base class, the next task is to modify our test XCUITest101UITest to the subclass of the base class and use common methods from the superclass.

Refactor UI Tests to Use Base Class

In order to refactor our original XCUITest101UITest, we can take a few actions, as mentioned below:

  • We don't need the recorded test, so, first, let's get rid of the testRecorded() test from our test class.
  • Next, we can rename our test method testRefactored() with something more sensible. As this is verifying the welcome message, let's rename this test with testWelcomeMessage()
  • We have to replace the superclass of the test from XCTestCase to XCUITestBase so that we can use all the common workflows from the base class.
  • Replace the instances of XCUIApplication() to app from the base class.

Once we are done with the above steps, our test class will look like this:

Now that our test class looks much better and tidier. We cut down our source code of 30+ lines to just 8 lines by using the base class. If you run this test by using the CMD+U key, you will see that our test is still passing without any issues. You can see the test logs from the Debug Area of Xcode, which is usually opened with the CMD+SHIFT+C (⇧⌘C)  key in Xcode 10. In the case of our tests, logs look like this when the test is running in the simulators:

In the end, you can see that test will assert the welcome message and pass.

Try It Yourself

The source code of this tutorial is available in the GitHub XCUITest101 repository in the baseclass branch here. You can download the source code and run the tests in the Xcode 10 by yourself. From the command line, you can get the source code like so:

 $ git clone https://github.com/Shashikant86/XCUITest101
 $ cd XCUITest101
 $ git checkout baseclass
 $ open XCUITest101.xcodeproj/

Once the project is opened in Xcode 10, press CMD+U to run the XCUITest.

Conclusion

In this post, we have abstracted the common code of XCUITest in the base class to avoid duplication. However, there is still much improvement needed to make our tests scalable and truly reusable. We will apply Swift's best test pattern to our XCUITest in the upcoming posts. Stay tuned.

Testing

Published at DZone with permission of Shashikant Jagtap, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Modern Test Automation With AI (LLM) and Playwright MCP
  • AI-Driven Test Automation Techniques for Multimodal Systems
  • Debugging With Confidence in the Age of Observability-First Systems
  • Accelerating Debugging in Integration Testing: An Efficient Search-Based Workflow for Impact Localization

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!