New software development methodologies are constantly emerging, and each promises to bring a lot of advantages compared to the traditional workflow. But in practice, any development approach may slow down your team. Thus, you need to thoroughly research any new approach before implementing it.
Nowadays, test-driven development (TDD) and behavior-driven development (BDD) are two extremely popular methodologies. They may seem similar at first sight, as both require creating tests before writing code. However, TDD and BDD have more differences than similarities.
In this article, we take a close look at the differences in the workflow of TDD and BDD, explore their pros and cons, and discover when it’s better to implement each of these development methods.
Test-driven development is a software development approach based on a short development cycle: tests are created first, and only enough code is written to pass a test. Then the code is refactored and the cycle repeated.
The development process with TDD is divided into three major stages:
- Red stage
- Define a small unit you need to develop. In order to do this, it’s important to break down the development process into the smallest possible tasks.
- Create a test for this task. Writing a test at this point makes a developer focus on the requirements instead of how features will be implemented. The test should be small and simple.
- Run all tests and see if the new test fails. This step ensures that the new test will actually test something.
- Green stage
- Write code that implements a previously defined unit. Keep the code short and simple, just enough to pass the test.
- Run all the tests again and see if they all pass.
- Refactor stage
- Refactor the code of the target unit while keeping all tests workable. At this stage, you can improve the code without adding any new functionalities.
As we can see from its workflow, TDD turns the usual development process upside down by putting writing tests prior to coding. But does it really make the process more efficient? Let’s take a closer look.
Applying TDD brings a lot of advantages to a project. Among the pros of TDD, this approach makes the development process more transparent and manageable.
Here are the key benefits of implementing TDD:
- Reduce development costs. TDD calls for dividing the development process into the smallest parts possible and testing every new piece of code. Therefore, the chances of discovering a bug in an already implemented unit increase. This approach also allows you to detect mistakes and architectural flaws at the design and coding stages of development. Fixing bugs at those stages is cheaper than during testing and operation.
- Focus on design and user-friendly interfaces. When developers write code, the first question they ask themselves is, What is the simplest way to implement this feature? Creating a test first makes them think, How should this feature work? and Will it be comfortable to use this feature?
- High level of code coverage. With TDD, you may achieve near 100% code coverage. This indicates a well-tested system, though code coverage cannot guarantee flawless app operation.
- Code visibility. TDD applies the keep it stupid simple principle to the development process. The desired behavior of each small unit is described in a test and is implemented in the simplest way possible. This means a developer doesn’t have to spend a lot of time figuring out the purpose of each module. Also, clean code is easier to maintain and refactor.
- Detailed documentation. In TDD, tests describe the desired behavior of each module, class, or function. Additionally, reading tests makes it easier for a new developer to understand the code.
Keyword-Driven Testing with Robot Framework
However, this doesn’t mean that TDD is a silver bullet for any development project.
Here are the main cons of TDD:
- A buggy test results in buggy code. If a test contains a bug, it will manifest itself in the code. You can spot this is to check your software modules manually. The risk of a buggy test also can be maintained by other practices like BDD, pair programming, code review.
- Logical and architectural mistakes can go unnoticed. Despite the high level of code coverage, TDD isn’t a panacea for bugs. If you make a mistake in the app architecture, it will cost you a lot of time and money to fix it. On the other hand, this process is painful both with and without TDD.
- Seemingly slows down the first stages of development. Creating tests before code takes a lot of time, especially on the first stages. It may seem like development progresses slowly because there’s no code implemented. That’s why TDD isn’t the first choice for startups. But in the long run, this approach actually speeds up development.
- Switching to TDD is hard for teams with no previous experience. TDD requires a lot of discipline, as it demands that all the steps be executed by the book. It might seem excessive for many developers. The most popular mistakes with TDD are not running the tests at the Red stage and covering complex features with one test. Both mistakes are common even for experienced development teams.
There’s a misconception that TDD is similar to unit testing — a software testing method that calls for creating automated tests for each unit, which can be a function or procedure. Testing units allows a developer to detect bugs at early stages and thus reduces the cost of development. Although TDD also calls for dividing the development process into small units, these two methods have very little in common.
While describing low-level processes, TDD is a more comprehensive approach than unit testing. In a traditional development workflow, unit tests are created when the code is already written. In TDD, tests are created before the code and they actually drive the development process, as the name suggests.
Behavior-driven development (BDD) is an example-based approach derived from TDD. BDD focuses on continuous communications and a shared understanding of the product between the development and product teams. This is achieved by creating scenarios of desired behavior.
Writing a scenario (in some BDD frameworks, a feature or executable specification) is the first step of development in BDD. A scenario contains a user’s story written in plain text using Gherkin syntax.
Gherkin is a test automation syntax that’s understandable to a non-programmer. It allows business analysts, project managers, and clients to describe the desired behavior of a feature using the Given/When/Then format. For example, if we’re creating a website and we want to describe a login procedure, we should create the following scenario:
Scenarios written in such a manner may remind you of project documentation, but they provide a more comprehensive description of software behavior. Also, any member of a team can understand such a description.
When scenarios are ready, they can be used as acceptance tests for the development team. The rest of the development process is the same as with TDD. Based on the provided scenarios, the development or QA team creates tests, then the development team writes the code and refactors it.
As we can see, BDD is an approach that involves managers, testers, and developers in discussing software functionality. Let’s take a look at the key pros and cons of BDD.
While sharing some stages of the development process with TDD, BDD also shares some of its advantages and disadvantages.
On the positive side, BDD:
- Ensures effective communication within the team. Creating a scenario requires a client representative, project owner, testers, and developers to work together. As a result, the whole project team has a unified understanding of the expected product behavior.
- Reduces quality control costs. BDD requires automating acceptance tests for all the expected user scenarios.
- Allows for more accurate task estimates. Since the expected functionality and behavior of the product are discussed before the development starts, there are fewer chances that you’ll need to add new features or change the architecture.
- Puts a strong emphasis on the user experience. Similar to TDD, working out scenarios and tests before writing code in BDD forces a development team to focus on the desired behavior of the software instead of implementing features.
- Creates living documentation. When tests fail because of an incorrect specification, you’re encouraged to update the executable specifications in the documentation. Also, having detailed scenarios and tests eases familiarization with the product for new team members.
The BDD approach, however, doesn’t fit all teams and products. Before implementing it in your project, keep in mind that BDD:
- Requires more time compared to the traditional development process. Putting together all the people involved in creating a scenario might be difficult, especially for big teams. Maintaining scenarios and tests also requires time and effort that some projects might consider an overhead.
- Slows down development if at least one of the three amigos is unavailable. In order to create a shared understanding of the product, three teams have to constantly collaborate: management, testing, and development. BDD adaptation will slow down development if there’s no mutual understanding between all team members.
- Is less efficient for small development teams and simple projects. If your team includes only a couple of developers who communicate daily with a tester and project manager, there’s no need to make them discuss scenarios. But creating tests before coding still provides advantages to small teams.
- Needs to be implemented at the start of the project. There’s little to no use for scenarios when you start creating and discussing them in the middle of the development process. Doing so will only make you rework already finished parts of the project. Retrofitting scenarios and tests to legacy code is nearly impossible and makes no sense.
Now that you know the basics of both development approaches, let’s compare TDD and BDD and take a look at the key differences between them.
There’s a popular saying that TDD is about doing things right and BDD is about doing the right things. Some steps of these approaches look the same, but there are actually a lot of differences between TDD and BDD.
TDD is focused on creating clear and understandable code that’s well covered with tests. This development method describes low-level processes: how to test and write code for each product feature. The Red – Green – Refactor algorithm:
- Drives you through development
- Puts the design prior to feature implementation
- Constantly tells you what to test and what to develop
- Doesn’t let you complicate the process
BDD, on the other hand, is an approach focused on communication inside the team and the correspondence of software behavior to the client’s expectations. It describes high-level development processes: desired behavior, use cases, and scenarios of software performance. Testing and coding recede into the background.
Let’s sum up some key differences of BDD vs TDD:
The choice between TDD or BDD depends on several factors:
- The size of your team
- The project scope and complexity of the product
- Your priorities during development (speed of implementation, time for development, desired level of test coverage, etc.)
- Level of communication between team members
TDD fits any project because it’s a more universal approach. Even if software is designed, developed, and tested by one or two people, they can still implement TDD. This approach focuses on the quality of individual units. However, it doesn’t ensure that software behaves correctly, as TDD doesn’t cover functionalities and doesn’t involve stakeholders in the development process.
BDD suits large teams, especially those who work on complex projects. This approach ensures and documents a joint understanding of product behavior. Due to the emphasis on correct product behavior, BDD is a useful approach for projects that concentrate on user actions in the spheres of e-commerce, government services, mobile applications, online games, and so on.
BDD is effective only for products with predictable results. The When/Given/Then pattern assumes that the result of each operation is defined before development starts. But if you develop a machine learning or artificial intelligence algorithm, for example, the Then parameter will change during the learning process. At the same time, the When and Given will remain the same. For such a project, using the BDD approach isn’t the best choice.
It’s common to combine TDD and BDD. Both approaches are closely related, as BDD was derived from TDD, and therefore they have similar stages. Combining TDD and BDD:
- Makes tests and the product understandable for the whole team
- Answers the questions How can we implement this feature? by creating a scenario and When should we implement this feature? by writing a test for it
- Increases test coverage
But keep in mind that implementing both TDD and BDD requires a lot of effort for maintaining all the tests your team creates.
Choosing the right development approach for a project is difficult. But while properly implementing an approach may be complex at first, choosing the right approach for your project saves time on development and improves the quality of the final product.
Whether you choose to implement test-driven or behavior-driven development, you’ll need strong QA and testing skills in your team. At Apriorit, we have vast experience working with both approaches. Contact us to find out more about our expertise and discuss your project!