Test automation with Behavior-Driven Development (BDD)
By Romano Roth and Marcel Stalder
Automating tests is a complex and demanding task. The iterative approach in the development process also means that the automated tests have to be continuously adapted. Behaviour-driven development (BDD) can be used to simplify and speed up test automation.
Agile and iterative software development with DevOps, including an automated build and deployment pipeline, requires good and automated test coverage.
Defining requirements for business software isn’t a trivial task. While the basic idea of a new functionality is usually communicated quickly, the challenges lie in the details. For example, product owners (PO), business analysts (BA) and requirement engineers (RE) use different forms to define requirements such as prose text, decision tables or sequence diagrams. Requirements are also communicated verbally to the developers (DEV) when something is questionable or ambiguous, for example, or if requirements have not been documented elsewhere.
This leads to several transformation steps:
1. The requirements from different sources and in different formats have to be communicated to the developers.
2. The developers convert the requirements into source code — firstly for the implementation itself and secondly for the automated tests.
3. The Quality Assurance (QA) managers, in turn, must be familiar not only with the requirements but also with how they have been implemented in practice.
Requirements, however, don’t usually remain fixed — they change. So the transformation process starts again and the delta to the existing implementation has to be identified. This step is time consuming and makes testing and quality assurance more difficult when changes are made — which isn’t ideal when you’re dealing with an automated CI/CD pipeline that has short development and test cycles.
The executable specification
What if the specification were executable? This would simplify the transformation steps, there would be fewer misunderstandings and the development process would be accelerated. An additional benefit is the documentation of the system’s functionality, which also really corresponds to the current implementation. This should result in better quality and therefore fewer bugs.
One possibility for an executable specification is behaviour-driven development (BDD) — an agile software development process that has its roots in test-driven development (TDD) and incorporates ideas from domain-driven design (DDD).
In BDD, the desired behaviour of a piece of software can be defined directly in a user story, for example:
The syntax Gherkin — which uses Given-When-Then as the basic structure for describing the precondition, the action and the expected result — is used for the definition. As it is pure text, the description of the behaviour can be used with various technologies, including:
- SpecFlow for .NET
- Cucumber.js for JavaScript
- Cucumber-JVM for Java
- Behave for Python
A practical example
Start with the specification of the desired behaviour. One example is a (simplified) calculation of the market value of a position in a securities portfolio:
The BDD tool reads this specification and generates a step definition for each Given/When/Then line. Step definitions are methods in the test code and are used as a link to the domain classes. The developers’ job is now to implement the generated step definitions based on the specification. The specification is then executed via the runner of the test framework used.
As the domain classes suggest, BDD is used here for unit tests to test the business logic. However, the automated execution of the specification is not limited to unit testing but can be used at all levels of the test pyramid. Many examples of BDD work at system level and automate UI tests using Selenium. Integration tests can, however, also be carried out to create or verify data in a database, for example.
The development process
The specifications are usually much more complex than the simplified practical example. This is why a solution design (SD) is created before the actual implementation process. To name but a few examples, this SD describes the actual situation, the target situation and the implementation steps (stories). The key element is the specification in Gherkin. Starting with the user story for the solution design, this spec is constantly expanded and refined. The spec is also a key element in the reviews to verify the requirements and the current implementation.
Behaviour-driven development (BDD) with the specification of the application behaviour in Gherkin is an advisable step for the automated testing of complex technical requirements. As the executable specification is already available at the start of the development work, test-driven development (TDD) is easy to implement. If a specification is to be consistent, everyone involved in the development process must use a common language, which is why domain-driven design (DDD) with a central and documented domain model is a good basis.
Thanks to behaviour-driven development (BDD) and an automated build and deployment pipeline, organisations can increase both feedback cycles and throughput speed. This allows them to react more quickly and impress their customers with constant innovation. Thanks to DevOps, processes are automated and optimised, from development to release and all the way to operations. This increases efficiency, which in turn reduces the costs associated with changes.