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
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
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
  1. DZone
  2. Coding
  3. Frameworks
  4. BDD for XCUITest With Swift Protocols and Extensions

BDD for XCUITest With Swift Protocols and Extensions

Learn how to apply BDD to your XCUITest UI testing for Swift code to make it more human-readable.

Shashikant Jagtap user avatar by
Shashikant Jagtap
·
Oct. 22, 18 · Tutorial
Like (1)
Save
Tweet
Share
8.10K Views

Join the DZone community and get the full member experience.

Join For Free

In the last post on DRY XCUITest with Base classes, we have abstracted our code in the base classes in order to avoid the duplication of the code. We have achieved this using the object-oriented inheritance approach. However, Swift is a protocol-oriented language, and we will see how we can use Swift protocols and extensions to make our XCUITests more human-readable. We will apply Behavior-Driven Development, a.k.a BDD, in the methodology of our XCUITest.

BDD in Swift 

The concept of BDD has been widely applied with Cucumber in Ruby and many other languages but BDD in Swift was always challenging because of a lack of proper BDD tools like Cucumber for Ruby, SpecfFlow for .NET, or Behat for PHP. There are libraries like XCTest-Gherkin and Cucumberish available to achieve BDD for iOS projects, but they are not as powerful as those for other languages. It’s still possible to make great use of native Swift features like protocols, extensions, and enumerations while writing acceptance tests in BDD style. We can use Swift’s protocol-oriented approach to write BDD style tests by capturing intended behavior in the form of Swift Protocol which is similar to the Features format in Gherkin. We can then think of all possible scenarios in the form of XCTest test methods which is similar to scenario titles in the Gherkin. We can also write steps in the form of methods in Given/When/Then a.k. a GWT using Swift extensions. 

XCUITest BDD in Action 

In our XCUITest101 app, we have a test already written to verify the welcome message. Now we will add another test in BDD or human-readable format like this: 

func testWelcomeMessageInBDDStyle() {
          givenILaunchedAnApp()
          whenITapOnEnter()
          thenIShouldSeeWelcomeMessage()
}

At this point, Xcode will give all the red errors use of unresolved Identifier givenILaunchedAnApp, which means we have to implement the steps to make it pass and do actions or assertions. Now, we will create another file inside the XCUITest101UITest target and call it WelcomeStepDefinitions.swift, as shown below. 

We have to implement all these steps in the Swift extension, and we can write an extension on top of the XCUITestBase class as shown below:

extension XCUITestBase {
     func givenILaunchedAnApp() {
          app.launch()
      }
     func whenITapOnEnter() {
          app.buttons["enter"].tap()
     }
     func thenIShouldSeeWelcomeMessage() {
          XCTAssert(app.staticTexts["Welcome to XCUITest"].exists)
    }
}

As you can see, in this extension, we have implemented all of our steps using the XCUITest methods that we used in the WelcomeMessage() test. Now, if you run the test, all the tests will pass.

Sprinkle Activities for Better Test Reporting

Now that we have applied the BDD concepts to our XCUITests to make them human-readable, we can make them more readable in the Xcode reports by applying the XCTActivity feature of XCTest for each step. With activities sprinkled on each step, we can write steps like this:

func givenILaunchedAnApp() {
     XCTContext.runActivity(named: "Given I Launched an App")  { _ in
          XCUIApplication().launch()
        }
}

We can apply this to all the remaining steps. Once we have implemented all the activities, our step definition file looks like this: 

Once you run this test, jump to the Xcode test report by right-clicking on the Play button from the test method. You will see the Xcode reports in a much more readable format. 

Now our XCUITest and Xcode test reports are much more readable since we’ve applied extensions. 

Add Protocols 

Swift protocols are similar to the interfaces or abstract classes from other languages. We can use Swift protocols to make contracts between test classes and test methods. Writing protocols is an optional step but it’s good to have it. In our case, we can write a protocol for the Welcome feature in the step definition file, which defines the test methods and makes the test class to adopt the protocol.

protocol Welcome {
    func testWelcomeMessage()
    func testWelcomeMessageInBDDStyle()
}

Now we can make our test class XCUITest101UITests class to adopt the Welcome protocol. The benefit of creating protocols is you can think of all the test scenarios well in advance and create the contract with your test classes. There is less possibility of forgetting the scenarios to implement. 

Try It Yourself

The source code used in this tutorial is available in the GitHub XCUITest101 repository and the protocol-bdd branch here. Download the repository and explore the XCUITest with protocol and extension. From the command line, you can get the source code.

 $ git clone https://github.com/Shashikant86/XCUITest101
 $ cd XCUITest101
 $ git checkout protoc0l-bdd
 $ open XCUITest101.xcodeproj/

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

Conclusion

In this post, we have applied the Behavior-Driven Development approach to make our XCUITest tests human-readable, scalable, and reusable for iOS app testing. We can reuse the step definition anywhere in the UI test target and create human-readable Xcode reports. However, we have our XCUIElements in the step definitions, which need to be scaled for reusability. In the next post, we will organize UI elements using Swift enumeration for better maintenance of XCUITests. Stay tuned. 

Protocol (object-oriented programming) Swift (programming language) Testing

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

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • AWS Cloud Migration: Best Practices and Pitfalls to Avoid
  • Select ChatGPT From SQL? You Bet!
  • 5 Factors When Selecting a Database
  • Top Three Docker Alternatives To Consider

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: