Software development can be overwhelming. There are tons of languages, frameworks, and tools to know about. Plus, there are processes to follow. For a developer, it’s often not the work of writing out code that’s difficult. The difficulty comes in determining what code to write, how to handle different cases, and trying to predict what the user needs. We can fix this by writing tests upfront. Doing this gives the developer a set of verifiably correct criteria to meet.
TDD (test-driven development), BDD (behavior-driven development), and ATDD (acceptance-test-driven development) all share “driven development” as part of their acronym. They drive development by making us prepare before development starts so that the development follows a predefined path. They share a focus on us spending time planning and writing tests before development. Having tests already in place provides clear expectations of what we need to create. And we developers work through these requirements uninterrupted and know we’re done when all tests succeed.
When it comes to process options, everyone has a success story behind why you should use theirs. I believe you should explore the different processes and use what works best for you and your team. In that spirit, I’m going to look at TDD, BDD, and ATDD and explain why you should try them out.
TDD (Test-Driven Development)
Test-driven development defines a process in which the developer writes tests before writing code. It follows a cycle of red > green > refactor. First, you’d write a test and see that it fails. This is the red stage. Then, you’d write the code to make the test pass. That’s the green stage. Last, you’d review the code and tests and make changes to simplify them without breaking any of the working tests. This is the refactor stage. You’d then repeat this cycle, completing all requirements. This is generally a developer-only practice, as developers take the project requirements, then write out the tests and the code to achieve those requirements. Once all tests are passing, the developer can hand off their work to testers or a business expert to verify.
Tests for TDD are written alongside the code and should be written in the same coding language as the rest of the system. Developers are already familiar with their language, so learning to write tests should be fairly easy. These tests tend to be technical in nature and may be difficult for non-developers to understand what’s being tested.
TDD is best applied when you have a known set of inputs with expected outputs. Especially when the logic to achieve those outputs is complex, TDD helps you simplify the complexity. Developers are able to break down large problems into very small chunks and focus on one thing at a time.
BDD (Behavior-Driven Development)
Behavior-driven development has a very specific structure for its approach. Instead of the developer writing tests, the business expert writes tests before development happens. These tests are written using a distinct sentence structure, Gherkin. When a test is written in this way, it can then be translated by software into an outline for developers in their coding language. Developers replace that outline with the code needed to make the tests true.
BDD is great when you have that business expert that knows exactly what they want the project to do. They can drive development through writing tests that express their intent while providing clear direction for developers.
Given, When, and Then
Write requirements using given, when, and then keywords to separate out segments of the sentence.
Given username of “user” and password of “password,” when the login button is pressed, then the user is sent to the home screen.
Given username of “user” tells the developer that the system will need to accept input for username and to use the value of “user” for this test. That developer would then use the translation software to generate an outline in code in order to focus on small pieces individually. The software automatically reuses outline pieces that have already been written. You can imagine how powerful that becomes as more tests are added.
Adding a new test that starts with Given username of “admin” means nothing has to change to use the value of “admin.” So you can see how adding new tests speeds up development by reusing existing logic. That means developers can focus on what’s new within the when or then segments of the test.
Everyone can understand what these tests cover because of their easy-to-understand format. When a test breaks, you can easily understand what broke. Because translating these tests into your programming language relies on software, you’ll need to make sure your team can use BDD.
If you’re unable to use BDD automation, you could still learn from this approach. Follow the given, when, and then style to write requirements, and you still gain the consistency and easy understanding this approach provides.
ATDD (Acceptance-Test-Driven Development)
Acceptance-test-driven development is about writing tests in collaboration with a business expert, developer, and tester. Again you want to write your tests before doing the coding work, and by bringing this group together, everyone gets on the same page before proceeding. The business expert brings their knowledge and is able to answer any questions at the beginning. Developers have an understanding of what the system currently does behind the scenes as well as what’s feasible within the technical limitations. Testers are able to bridge both sides while also knowing how to test that the requirements have been completed. By working together to define the tests and requirements, the team is able to be flexible to best suit the goal of the project.
During this collaboration, testers should implement all of the tests needed to accept that development has been completed. These tests are usually a higher level than those written with TDD, but they will likely not be full UI automation tests. You want these tests to prove that with a given set of inputs the expected output is created. Think of these tests as a matrix of data inputs and outputs that automate your system. Developers now write their code with validation tests already in place. To learn about the cucumber tool and how to use it for BDD or ATDD, look into our training course.
ATDD is valuable for spreading knowledge throughout your team. Each member provides different expertise, but through this exchange, everyone gains a deeper understanding. An added benefit of this approach is found when unanticipated questions arise. Developers or testers can use the intent expressed by the business expert to answer questions without having to wait.
It’s About Development
You might think that because each of these approaches uses writing tests as a key part of the process—that this is all about the tests. However, they’re all really about the development effort. By writing tests first, you’re defining what needs to be solved for. Developers get to focus on making their code work, rather than on whether or not their code is doing to the right thing. This tends to speed up development time and reduces the likelihood of bugs. On top of all of that, you end up with tests as an extra bonus.
How do you decide which one to go with? You don’t need to choose just one. Depending on your situation and team, you can use positive aspects of each of them. You can also combine them. You might use ATDD to gain early collaboration while the developer follows TDD for their work. Use the given, when, and then format from BDD to define your acceptance criteria in ATDD without the translation to code. Find what works best for you and your team.
Software development is not about following a rigid structure. It’s all about constant improvement and changing to find what works well.