Setting up Behavior-Driven Development in Swift

Benjamin Dumont
Just-Tech-IT
Published in
5 min readAug 6, 2020

--

Behavior-Driven Development (BDD) is an Agile software development process that encourages collaboration among developers, QA and non-technical or business participants in a software project. It encourages teams to use conversation and concrete examples to formalize a shared understanding of how the application should behave¹. Examples may be written in some feature files using the Gherkin language or in other format (like in code directly). The advantage of Gherkin is that all team profiles can read/write tests since it is not a technical language.

Pre-requisite

You have to specify all the examples at least during the 3 amigos / example mapping. For this article, we will use a trivial example³:

The aim is to apply a logical AND between 2 booleans.

Librairies

Unfortunately, there are not a lot of librairies for writing BDD in Swift. This is a non exhaustive list of librairies I found:

So, for this article, I chose XCTest-Gherkin because:

  • It is written in Swift
  • Features can be written in code format AND in Gherkin format (in a feature file)
  • Easy to use
  • The last commit is not so old (4 months from now)
  • Can be installed with Cocoapods

You can see the documentation and code for XCTest-Gherkin here.

Initialization

With BDD, you should write your tests before implementing the code (and use the different phases called red — green — refactor). I won’t do that in this article since I want to show you how to implement tests based on Gherkin file (and I think writing tests after is better to understand it) but you should not do this in real life.

So first, you have to create a project with Unit Tests in XCode. Then, using the terminal, go to your project folder and run the following command (assuming that Cocoapods is installed):

Then, a Podfile should be created. You can add the pod in your Test target :

Note: I am using the subspec “Native” in order to use feature files. If you don’t want to use feature file (so your scenario are written in code), you don’t need it (so you will have pod ‘XCTest-Gherkin’).

Now, you can install pods (using the pod install command) and open the xcworkspace file in XCode.

Application

As said before, we will start by writing code for the application. So, let’s start with the following code:

Scenario

Inside your test target, you can create a .feature file to write Gherkin feature.

Using the example mapping, we have 4 scenarios:

Tests

Now we will write our tests:

In the first part, we define which scenario to run per method. In the second part, we define the different steps. This is where you write the code you need corresponding to the steps in the Gherkin file.

Note: Pay attention to your steps definitions (which should be identical to the ones defined in your Gherkin file). If not, you may have some crashes on your tests. This is the kind of error message you can have:

  • No scenario found with name: FAKE
  • Step definition not found for ‘Fake step’. Precondition failed: Some step definitions not found for the scenario: firstbool false, secondbool false

Refactor

Everything is working as desired. But some tests are redundant. So we can refactor them by passing a parameter for example.

Here, we use a String extension to simplify the String to Boolean conversion. As you can see, at each step, we pass a parameter which can be true or false.

There are different ways to pass parameters, this is described in the XCTest-Gherkin Github repository. For example, you can use this²:

Scenario Outline

With Gherkin, we can use Scenario Outlines to use an array of parameters in the Gherkin file. In this case, you define the parameters using the following syntax:

And we can now use this code for testing:

The scenario “all together” is a concise approach: thanks to the scenario outline, all my tests may be written in a unique scenario. It may be harder to debug but it is easier to read.

Capturing different values

Previously, we saw how to capture different possible values in our step:

It becomes more complicated to read if there are several possible values. But there is an option with enum to use:

In my opinion, you have a better readability using this method but be careful, you have to differentiate the steps before the captured group (if not, you may have a step duplications… and a crash). And you can remove all your utilities extensions (like the String extension for boolean conversion) since the enum is now responsible for that (and no need of managing nil value anymore).

Regex matching

The default regex matching is not very strong since it doesn’t care about the beginning/end of a line. But you can force this with the “^” and “$” characters:

It works but I don’t find it pretty. You can use the method step with a parameter called “exactly” which does the trick for you (adding the “^” and “$” characters):

Unfortunately, for now, it is not possible (in the pod) to use the “exactly” parameter with captured groups. But you can use this feature by adding the following code in your application test target:

Tools

  • Gherkin Formatter: there are several Gherkin formatters on websites, on chrome extensions, on applications, XCode extensions... Choose the one that fits your needs. This is an example of what it can do for you:

Before using a formatter:

After using a formatter⁴:

Conclusion

BDD with Gherkin enforce the quality of an application by creating some functional tests which could be described by everyone inside a team (Product Owner, Business Analyst, Tester & Developer). It may be harder to implement than unit testing but is more powerful since it deals with features and is closer to real life. In addition, it can generate documentation that will never be outdated. It may take some time for developers to implement it but this time will be reduced the more you practice, and the technical debt too. You should try it! :)

You can find the example here.

For more informations, you can read this article about pros and cons of BDD.

[1] Wikipedia

[2] XCTest-Gherkin, Step definitions section

[3] The tool used for generating the picture is draft.io

[4] The tool used for formatting is AssertThat

--

--