Introducing Protocol-Oriented BDD in Swift for iOS Apps: Part 2
In Part 2 of this tutorial, see how to use Swift protocols, extensions, and enumerations with Behavior Driven Development, or BDD, in iOS mobile apps.
Join the DZone community and get the full member experience.
Join For FreeThis article continues from Part 1 of this tutorial, found here.
Refactor Elements Using Enumerations
We have implemented all the features using protocol-oriented BDD approach. It’s time to refactor and tidy everything up.
In the Greeter+Extensions.swift
file, we have placed XCUIElements randomly. We can use Swift Enumerations to store all the elements for that particular feature. Let’s create a new file Greeter+Enum.swift and store the button and static text.
import XCTest enum GreeterElements {
static
let greetButton = XCUIApplication().buttons["Greet"] static
let welcomeText = XCUIApplication().staticTexts["Welcome to POP"]
}
We can use those elements in the extensions so that our steps become more readable and look like this:
import XCTest extension Greetable {
func givenTheAppIsLaunched() {
XCUIApplication().launch()
}
func thenIShouldSeeGreetButton() {
XCTAssertTrue(GreeterElements.greetButton.exists)
}
func whenITapGreetButton() {
GreeterElements.greetButton.tap()
}
func thenIShouldSeeWelcomeMessage() {
XCTAssertTrue(GreeterElements.welcomeText.exists)
}
}
Now we have reached to the point where we can do BDD using Protocol, Extensions, and Enums; however, we have performed a lot of steps to achieve this. It would be great if we could quickly set up the framework code and get going with BDD. XCFit is the solution to get started quickly. In this section, we will see how we can save time by using XCFit templates and pre-defined steps.
Automate Protocol Oriented BDD Using XCFit
XCFit is a full stack BDD framework for the iOS applications, It provides automated Xcode template as well as pre-defined steps. You can install XCFit templates package using RubyGems or HomeBrew. Let’s use RubyGems for now.
$ sudo gem install xcfit
Use Automated XCFit Xcode Templates
XCFit has automated Xcode templates which provide skeleton code for the protocol-oriented BDD. The templates with Xcode Groups and the required code can be downloaded using command.
$ xcfit setup_xcode_templates
Now we have XCFit Xcode templates installed, which can be used inside the app as new targets. In our Greeter app, select File->New->Target and choose iOS, and you will see new targets available there. Select ‘Protocol BDD’ for the Protocol Oriented BDD and give it a name or keep it as the default as GreeterProtocolBDDTests. You will see the template code is automatically generated for us. You probably need to delete the XCUI Template test file YOUR_TARGET_NAME_Test.swift as we won’t be using this file.
Now, rename the template file to use Greeter feature, so we need to rename following file in the newly created target:
- Feature+Protocol.swift –> Greeter+Protocol.swift
- Feature+Extension.swift —> Greeter+Extnsion.swift
- Feature+Enum —-> Greeter+Enum.swift
- Feature+Test.swift —> Greeter+Test.swift
Replace the template code with the code we implemented above and we will see the test is still passing for the new XCFit target.
Use Pre-defined Steps From XCFit
The XCFit Swift framework provides lots of pre-defined steps that can be used straightaway in the test with no need for implementation. It means step definitions are already implemented for us so we don’t need to write extensions. In order to use pre-defined steps, we need to import the XCFit Swift framework into our target. Let’s use GreeterProtocolBDDTests target for that. We can either use CocoaPods Or Carthage to import XCFit. You can find a detailed explanation on how to do this here. We will use CocoaPods here. We can generate template Podfile using XCFit command:
$ xcfit setup_xcfit_podfile
This will setup Podfile in our project; we need to replace PROTOCOL_BDD_TARGET = "GreeterProtocolBDDTests." Make sure unwanted targets in the Podfile are commented. Now we can install dependencies using:
$ pod install
We have to close the current Xcode session and open Greeter.xcworkspace.
Now that, we have imported XCFit library. Let’s create a new test in the GreeterProtocolBDDTests target to use XCFit pre-defined steps. We need to import ‘XCFit’ in the test as well as extend the test class to XCFit framework to use pre-defined steps.
- Create a new Swift file inside Tests group call it as GreeterPredefinedTest.swift.
- Import the XCFit Framework and Extend the test class to XCFit as well as confirm to Greetable protocol.
- In the both test methods we can now use XCFit pre-defined steps so that our class looks like this:
import Foundation import XCTest import XCFit class GreeterPredefinedTests: XCFit, Greetable { override func setUp() { super.setUp() continueAfterFailure = false XCUIApplication().launch() } override func tearDown() { super.tearDown() } func testHomeScreenHasGreetButton() { givenTheAppIsLaunched() thenIShouldSee(GreeterElements.greetButton) } func testUserShouldGetWelcomeMessageOnceEntered() { givenTheAppIsLaunched() whenITap(on: GreeterElements.greetButton) thenIShouldSee(GreeterElements.welcomeText) } }
Note that we haven’t implemented single steps in the above class. These steps are coming from XCFit pre-defined steps- still, our tests will pass.
Running Scenarios on CI Server
It’s not enough to run scenarios in the Xcode itself; we also need to script those scenarios so that it can be run from the command line or with any Continuous Integration server.
Install Fastlane
Fastlane is a very popular open-source tool used for the automation of the iOS development task. Fastlane can be installed using RubyGems using the command:
$ sudo gem install fastlane
We can run the tests using Fastlane Scan, however, we need to do a little bit of setup including writing Fastfile and configuring scan options. It might be bit tricky for any iOS developer who doesn’t have Ruby programming knowledge. Thankfully XCFit provides template for setting up Fastfile for us.
Setup Fastlane using XCFit Template
XCFit has pre-defined template for the Fastfile with all the required configuration to run our BDD Scenario using Fastlane Scan. XCFit will setup Fastlane directory with Fastfile for us so that we don’t need to worry about setting from scratch.
$ xcfit setup_xcfit_fastfile
This will create Fastfile with scan configuration. We need to replace the values for the constants like WORKSPACE, DESTINATION, XCFIT_SCHEME, etc in the Fastfile, then we should be able to run ‘xcfit’ lane.
$ faslane xcfit
You can see the tests executing from command line.
You can see that this lane is also creating reports in JUnit as well as HTML format for our test scenarios. It would super easy to plug this setup into any Continuous Integration server.
Benefits of The Protocol Oriented BDD Approach
There are few benefits of doing Behaviour Driven Development using protocol-oriented approach which are as follows:
- We can use native Swift Features like protocols, extensions, and enumeration freely in the test code without any restrictions.
- We can use Apple’s own XCTest Framework to drive development without any third party libraries.
- We are not restricted to use Gherkin syntax. We can customize the language as we want.
- We can re-use any step within our test target. We can avoid duplication using writing smart and reusable steps.
- We can get started with protocol-oriented BDD framework within few minutes using XCFit Xcode templates.
However, there are few caveats you may find using BDD in protocol-oriented way, but they are trivial.
- Because of the limitation of XCTest, we can not parameterize the scenarios using different examples.
- We may not get the feel of proper BDD as programmers do not get notified of the unimplemented steps.
- The reporting of the scenario execution to non-technical people might be tricky.
Source Code On Github
You can find entire source code of this tutorial on Github repo – ProtocolOrientedBDD-Swift.
You can clone the source code and execute the tests using either Xcode or Fastlane.
$ git clone git@github.com:Shashikant86/ProtocolOrientedBDD-Swift.git $ fastlane xcfit
I hope you will like this approach of developing apps using BDD in a protocol-oriented way. This is my own idea of implementing it in a protocol-oriented way so feel free to share your thoughts and suggest areas where it can be improved. Look forward your replies in the comment below!
Published at DZone with permission of Shashikant Jagtap, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments