Apple has recently announced new features in XCUITest framework. One of the great feature is Activities which can be used to organise XCTest actions into human readable activities. The new protocol XCTActivity has been added to the XCTest framework.
What is Activities in XCUITests
Usually UI Tests perform lot of actions during execution e.g tapping buttons, swiping etc. As of now, XCTest reports inside Xcode shows all the actions in the test reports which is not particularly readable. Activities is the way to organise those actions into group by giving meaningful name so XCTest result will use that activity name in the result to make it more readable. You can read more about activities on Apple official documentations here. We can sprinkle activities on any set of actions
What’s BDD
BDD a.k.a Behaviour Driven Development is a process of developing an application by using executable specifications in Gherkin or similar so that programmers can use those specifications for development and business people can use them requirement specification or living documentation. BDD is an outside-in development methodology. You can read more about BDD here
Can We BDD with XCTActivity ?
Let’s try to answer this question. Imaging we are going to create an Greeter app which greet user when entered. So our app has two requirements
- App should have enter button
- When user tap on enter button, it should display greeting message
Let’s write Gherkin feature file of this:
1 2 3 4 5 6 7 |
Feature: Greet users Scenario: User Should see Greeting message Given application is launched When user tap on enter button Then I should see greeting message |
Now that, we have written all our requirements in the human readable format. Let’s dive into the code. Create new single view application inside Xcode name it Greeter and include UI tests.
In our UI Test we can add the test with scenario name and Activities with step names like this
1 2 3 4 5 6 7 8 9 10 |
func testUserShouldSeeGreetingsMessage() { XCTContext.runActivity(named: "Given application is launched") { _ in XCUIApplication().launch() } XCTContext.runActivity(named: "When user tap on enter button") { _ in XCUIApplication().buttons["enter"].tap() } XCTContext.runActivity(named: "Then I should see greeting message") { _ in XCTAssertTrue(XCUIApplication().staticTexts["Welcome"].exists) } |
When we run test first time it will fail as don’t have button or static text.
We can implement button and static easily. Add button to main storyboard with accessibility Identifier ‘enter’ and add label ‘welcomeText’. Now create IBAction to button to display ‘Welcome’ text when tapped. Our ViewController will look like this:
1 2 3 4 |
@IBOutlet weak var welcomeText: UILabel! @IBAction func welcomeUser(_ sender: Any) { welcomeText.text = "Welcome" } |
We will have our BDD scenario fully implemented and we can see the test goes green.
Source Code:
The source code of this demo project is available on Github ‘XCTActivity-BDD‘
Now that, we have implemented our first BDD scenario using Activities features of XCUITest. The question is can we carry on doing BDD with this ?
Probably not, because Activities has some limitations such as
- We can’t run activity outside of test method.
- We can not re-use activities for other tests that means will have lot os duplication.
- The activities will only reflects in the Xcode reports but our test won’t look great. Test will have activities all over.
- The test reports will be available only inside Xcode and it’s hard to use these reports as living documentation
- The BDD scenarios reporting format isn’t readable even used with xcpretty as it will only shows test name inside the html reports not the actual activities.
What’s missing ?
The XCTActivity is a great feature to organise the test actions but it’s still missing out some points that can be useful in order to avoid duplication. Some of the missing points would be
- Re-usabliliy of XCTActivity so that activities can be shared across the tests.
- Abstraction of runActivity(named:block:) is hard.
- Test report formatter to display activities outside Xcode.
Is there any way you can think we can still achieve BDD using the existing features of XCTActivity What do you think ? I would love o hear your opinion in the comment or email.