From TDD to BDD: When to Switch and How to Apply

While the testing phase is essential for any development process, it can be accomplished using different approaches. The two most mainstream software development approaches of the moment are Test Driven Development (TDD) and Behavior Driven Development (BDD). But if TDD has long been highly appreciated for its efficiency, what can be the point to move to BDD? Let’s see when working with the BDD approach will pay off and how to better execute these tests.

Moving from TDD to BDD: Considering the Approach Change

Test-driven Development has long become an acknowledged way for developers to check the accuracy and efficiency of the code. Its working principle has proved to be effective in most cases: developers write a test before writing functional code in order to specify the requirements, then, after the test fails, they pass to writing and implementing the minimal code needed for passing the test. This practice of writing failing tests, known as the ‘red-green-refactor’ cycle, focuses on writing an application code per one unit, thus contributing to a more structured project architecture and rational coding, with as minimum code as possible.

Despite its efficient results, the approach is encumbered with certain difficulties:

  • Time consuming process. The whole ‘Red-Green-Refactor’ cycle of the TDD work requires investment of time into each part. This adds major time to the first iteration of the project and influences the costs of the project. It pays off in the long run saving time spent on QA testing and debugging, but equally it can turn out to be unnecessary. Plus, for the same reason, TDD is hard to implement for rapid development.
  • Need for updating tests. With TDD, if you update the function, even without changing the inputs and outputs, you must also update the test. So if the algorithms tend to be changed, tweaked or fine-tuned in the project, time investment into TDD can be unjustified.
Behavior-driven Development testing appeared as an alternative to the TDD method in the early 2000s. Its approach, though also test-first, is focused on the end user’s needs and his or her behavior to satisfy them by using the so-called Executable Scenarios.

BDD approach uses its own terminology:

  • Story, which represents an automatically executable increment of business functionality, i.e. describes a need/problem;
  • Scenario, which represents a concrete example of the behavior of the system and provides specific, computer-readable steps to use the feature under certain circumstance. A typical scenario is written in a domain-specific language (DSL) like Gherkin, which makes it comprehensible for non-tech specialists as well;
  • Feature, which is an action to be taken by the end user (logging into the system, getting registered, etc.);
  • Steps, which need to be taken to implement the feature and which can be of three types: Given, When and Then (they are also called BDD Keywords).

This results in distinctive peculiarities of the approach:

  • Fixing the desired outcome in a ubiquitous language. While TDD presents a set of tests written in a proper programming code, BDD tests describe scenarios in plain English which can be understood not solely by a development team but all the stakeholders: Product Managers, QA engineers, Business Analysts. This puts the BDD approach in perfect correlation with the main approaches of the moment: the Agile practices and the Domain-driven Design approach, which also focuses on elaborating a ubiquitous language.
  • Solving the problem of communication. Stemming from the previous characteristic, BDD provides stronger collaboration between technical specialists, business team and machines. Each of these so called ‘three amigos’ solves its own set of tasks : a business person, having business insights, answers the question ‘Is this feature valuable?’; a developer specifies the solution space, i.e. the technological part of implementing a feature; a tester knows the problem space and the flows in the system which are associated with the feature implementation. Thus, it improves the accuracy of meeting the project requirements
  • Removing the focus from the technical side to the aim of the software. Something which runs with developers – focusing on technical problems in order to solve them – gets quite different with BDD. Here, in order to successfully accomplish BDD testing, one needs to concentrate on the value of a feature and what it provides to the business in the end. Therefore, any change in the functionality accommodates less impact on BDD tests as compared to TDD.
It doesn’t mean that BDD is going to replace TDD in the development cycle for all projects. There is a general distinction between them: TDD is better used for systems that have 3rd party API calls, cron jobs, data exports/imports and other side implementations, whereas BDD works as a better solution for ecommerce websites or HR systems, i.e. for custom web development projects driven by actions of the end user. But in most cases both solutions can be applied together, thus each solving its particular tasks: BDD describes a system’s behavior, while TDD explains how this behavior should be implemented.
Have any questions? Ask our team!

Applying BDD to Your Project: Cucumber and Cucumber-inspired Frameworks

There are a number of frameworks on the market aimed at facilitating the BDD testing process, with every major programming language having at least one specific BDD automation testing framework. The most popular one is Cucumber, with many other tools copying it for a particular programming language.

Cucumber: Supporting Several Software Platforms

Cucumber by itself is written in Ruby programming language and is taken as its background RoR web application framework. However, it can also be used to test the code written in other programming languages like JAVA, .NET, Groovy etc., with popular implementations such as CucumberJS, CucumberJVM, Cucumber Lua and others. The central role in Cucumber is played by the Gherkin language, which uses plain-text English phrases comprehended by non-tech specialists.  

Cucumber tests are executed in two steps:

  • Scenario Steps, which are fixed in a Feature File. It contains scenarios following the Given-When-Then structure and possessing the ‘.feature’ file extension in order to make Cucumber automatically detect them.
A Feature File contains:
    • Title
    • Story, which follows three lines: In order to [Benefit]; As a [Role]; I need to [Action]. The Story is not parsed by the framework, but it provides a context for specialists who will be reading the scenario.
    • Scenario, i.e. the body of the feature, containing Steps.
    • Steps, i.e. lines in a scenario. There are three main kinds of steps (sometimes added by And and But Steps):
      • Given steps (initial context: what has happened before),
      • When steps (event: which actions the user performs), and
      • Then steps (outcomes: the desired result for the user).
  • Step Definitions, contained in a Step Definition File and aimed at converting scenarios into actions, i.e. into executable code. Cucumber parses a Feature File and searches for Step Definitions that match the Scenario Steps.
The way Cucumber functions makes it a favorite tool among developers. million downloads in the first three years and 5 million downloads three years later prove it). However, there are Cucumber-clone tools for automated testing, for programming languages: Behat for PHP, SpecFlow for C#, Behave for Python, and others.

What’s the point of using clones when a developer can go for Cucumber?

  • Speed. Cucumber is based on Ruby, and in order to run a test of a product written in another language, a developer needs wires, proxies and other instruments, and this results in considerably slower speed rates compared to native tools.
  • Extensibility. It can be quite hard to find tech specialists with the same level of expertise in Ruby and the second programming language, which product to-be-tested is written in. As all learning resources and examples for Cucumber are Ruby code, it can lead to evident miscomprehension problems.
That’s why, relying on the Cucumber’s logical structure, the clone testing frameworks provide support for a specific programming language, plus enhance it with their own features. Let’s check this similarity at the example of Behat.

Behat: Automated Testing for PHP Products

Behat is an open source BDD-centered PHP framework. But unlike Cucumber, which supports many languages, Behat only works with PHP products. Behat requirements are fixed in the same Gherkin language, which puts the scenario in line with fixed phrases which Behat can parse. That’s why the process of executing a test is pretty much the same as with Cucumber.     However, Behat remains a favorite BDD testing tool among PHP developers for the above mentioned speed and extensibility advantages , plus for additional extensions which facilitate the test execution within the framework. These extensions simulate a browser, in order to test the steps, which in their turn reflect user behavior, against the expected outcomes.

There are two main types of browser emulators:

  • Headless browser emulators (Goutte), which have no UI visual elements and test a product in an environment close to the one of a real browser. Their speed and simplicity are their advantages, but they have no JS/AJAX support;
  • Browser controllers (Selenium, Sahi), for running a product on a real-time browser. They are more powerful and support JS/AJAX interactions on the page, but can function quite slowly.
These two types of emulators complement each other, and companies like R-Style Lab that provide PHP development services usually use them jointly for the same project. However, these have fundamental differences since they use different APIs. The solution, which hides these different APIs behind a single one is called Mink, and it serves as a browser emulator abstraction layer between the emulators themselves and Behat. This essentially means for a developer that they can switch from one to another browser emulator quite seamlessly as all of them will function via the same PHP API abstraction layer. Mink talks to browser emulators through Mink drivers. Some of the drivers are built solely for a particular browser emulator (like SahiDriver or GoutteDriver), while some offer a direct control of a browser itself, like ChromeDriver which allows to control Chrome without the overhead of Selenium.
Using BDD approach in some cases can prove truly efficient and would in the long run save time and effort when the project comes to its QA phase. Moreover, it gives more confidence to developers and customers that the project will run smoothly afterwards. A growing use of such tools as the universal Cucumber and similar tools (Behat, Behave, etc.), developed for a particular programming language, add to the growing popularity of the testing approach.
Did you like our post?

Subscribe to our monthly IoT digest!

Please, enter a valid email address
Please, agree with our privacy policy

Check out services we provide!

Get a Free Quote Now!

Popular Posts

Link copied to clipboard

Get 3 bonuses now!

Just Share Your Project Idea
(We'll Keep It Safe!)
& Get Your Bonuses for Free!

get for free now