Test-driven development (TDD) is a software development principle and practice; a way of developing valuable software. Test-driven development is closely tied to the test-first programming method of eXtreme Programming (XP). Kent Beck rediscovered and popularized this practice in his book "Test Driven Development by Example." (1).
In his book, Beck illustrates the development cycle as:
Each feature begins as a test. To write such a test, the developer must understand the requirements and specifications of the feature. The developer then executes all the tests to ensure the newest one fails. Otherwise, the new code will likely be worthless. The next step is to create code to make the test pass. One critical piece that Beck eludes to but doesn't call out specifically is that after the code has been refactored, the tests should be run again. Then once all tests pass, then the developer knows the new code meets the test criteria. An evolving code base must be refactored, or cleaned up, regularly. The cycle continues as the functionality evolves.
In more simple terms, TDD can be explained as Red, Green, Clean.
There are many advantages to TDD. It enables developers to take small steps when writing software. It is far more productive than attempting to code in large steps. For example, assume you add some new functional code, compile, and test it. Chances are pretty good that your tests will be broken by defects that exist in the new code. It is much easier to find and then fix those defects if you've written two new lines of code than two thousand lines. Lastly, testing early and often (finding and fixing) is much less costly than finding and fixing later in the development lifecycle.
So let's take it one step further with behavioral-driven development (BDD). While TDD focuses on the developer's point of view on how the feature should work, BDD focuses on the user's perspective on how the feature should behave. Thus, BDD is an evolution of TDD.
Behavioral-driven development was introduced by Dan North with issues he continually came across in test-driven development. (2) He suggested that instead of simply writing tests, developers should think of specifying behaviors, which is how the users want the feature to behave. In BDD, you should always start with the features that are most important to the users. Through collaboration and continual feedback, the practice of knowing what is most important becomes clearer.
To accomplish this, BDD focuses on how a desired behavior should be specified. Implying that the desired behavior has business value. Thus, it is critical to specify this business value, which has now become the standard for documenting user requirements (stories):
In the past, we were focused on who the feature was being developed for and what function they were performing. However, a critical piece was missing; why does this user want to perform this function. If we don't know why, then do we really need that feature?
While, there are no formal requirements for documenting these user stories for BDD, Dan North suggested the Given/When/Then format of expressing various scenarios, called acceptance criteria. Similar to the format of a user story, the acceptance criteria has purpose:
Given is the state of the application before the test, which may be multiple statements about this state. When represents the programmatic action under test or changes to the application. And finally, Then references the state after the test. The scenarios are written in business terms with no reference to the UI through which the actions occur. The scenarios should cover positive (happy path), negative and edge cases.
Below is a very simplistic feature that we can all relate to and its associated scenarios:
Story: Network logon password.
While this may seem like a lot of scenarios or test cases, the possibilities of the business rules stated above are almost unlimited. With these 10 simple scenarios, we can be assured the code and behaviors are correct when all 10 pass.
This format is referred to as the Gherkin language, which has a syntax similar to the above example. The term Gherkin is specific to the Cucumber and jBehave software tools. (4)
While there are those who believe BDD is TDD done correctly, it is based on a set of best practices focused on the users. With BDD, there is a paradigm shift from thinking that software development is all about the technical solutions, to focusing on the purpose of the software to those actually using it.
So why do this at all? As previously mentioned, BDD shifts the thinking from the developer's point of view to that of the users of the system. However, that is not a reason for doing so. I will answer that question initially with another question. What enables us to be agile, to deliver software in small increments, to continually incorporate feedback, to refactor with every increment?
Agility = Automated tests that run on demand
Expressing test scenarios in the above-mentioned format and within the construct of BDD, will greatly increase the ability to automate tests. While there will always be testing that cannot be automated such as exploratory testing, it will increase productivity, reduce risk, and increase overall quality of the software being developed.
This is just the tip of the iceberg in regards to both TDD and BDD. For more information on this subject, you can review Dan North's and the jBehave websites.