What is TDD?
As its name implies, Test-Driven Development puts the development of test scripts ahead of the actual code that will be tested. Using TDD, developers must ponder the end goals of their code first in a way that is more tangible than simply reading a specification. They are actually implementing the end behaviours in the form of tests, which is a process requiring much stronger cognitive involvement.
A developer starts with TDD by writing test scripts that cover the functional happy path in the code to be written. That is, the first pass of these scripts exercises the core functionality of the code not yet written without attempting to explore border conditions, performance, security issues and the like. Those tests might be included in the test scripts as the code develops, but they are more likely to be handled in later test phases.
The next step in TDD is executing the test scripts, which obviously fail, to ensure they fail gracefully and to verify that each test step is executed. At that point, code is written that fulfills the requirements of the test, which was originally written to fulfill the software specification. Once the code and its test runs successfully, the developer may refactor the code and verify it again with the test script until he or she is satisfied with the results.
As code development progresses, developers will be tempted to get ahead of the test script by adding more code before expanding the test script or creating additional scripts. This behaviour is the natural proclivity of developers who want to get on with the project, but it breaks the virtuous cycle of TDD and its cognitive benefit in driving development of the correct code.
What is BDD?
Behaviour-Driven Development can be thought of as an enhancement of TDD in that it, too, puts the implementation of the goals of the software, as represented by test scripts or scenarios, ahead of the actual code implementation. The overall purpose is much the same as TDD, which is to provide a powerful shift in point of view. This often results in producing the right code the first time or revealing defects in the requirements even before the first line of code is created.
The difference between TDD and BDD is subtle but significant. The main distinction of BDD is that the behavioral tests are written through collaboration by as many of the stakeholders in the software development process as possible including business, planning, marketing, sales, Ops and QA.
Everyone involved should be able to understand the test code/scenario as well as contribute to it. Thus, BDD tests express their actions in a natural language style, similar to what a tester might put in the comments of a traditional test script written in a programming language. Tools exist to assist this process of which Cucumber is probably the most well-known, which also automates the process of scenario creation and testing.
When Each Approach Is Most Useful
When deciding to use either TDD or BDD, consider the makeup of the team charged with turning the software requirements into a coding specification. If your team is composed solely of programmers, then using TDD makes good sense. However, if your project requires communication across organizational units, then BDD supports that higher level of collaboration better.
In fact, BDD almost demands that everyone from business analysts to production teams become involved in the earliest phases of software development. Bear in mind that starting with BDD may not be an easy process, since participants will initially speak in different terms and express concerns of varying relevance to one another. The result, however, is the removal of ambiguities and the creation of common understandings at the earliest stages of development, which is invaluable to ongoing project stability.
In short, both Test-Driven Development and Behaviour-Driven Development are “outside-in” processes utilized to reveal and test assumptions about the functional and behavioural aspects of software even before the first lines of code are typed out. The main distinction in their use is the level of collaboration present or desired in the organization utilizing them.
Both approaches provide opportunities for early defect detection in software design and implementation when the removal of such defects is typically less costly. Both result in creating requirements and code that are more testable with more stable interfaces. They also enhance the original software specification by documenting implicit assumptions made by various stakeholders including the end users.