Chapter 7. BDD – Working Together with the Whole Team

 

"I'm not a great programmer; I'm just a good programmer with great habits."

 
 --Kent Beck

Everything we did until now is related to techniques that can be applied only by developers for developers. Customers, business representatives, and other parties that are not capable of reading and understanding code were not involved in the process.

TDD can be much more than what we did until now. We can define requirements, discuss them with the client, and get agreement as to what should be developed. We can use those same requirements and make them executable so that they drive and validate our development. We can use ubiquitous language to write acceptance criteria. All this, and more, is accomplished with a flavor of TDD called behavior-driven development (BDD).

We'll develop a Books Store application using a BDD approach. We'll define acceptance criteria in English, make the implementation of each feature separately, confirm that it is working correctly by running BDD scenarios and, if required, refactor the code to accomplish the desired level of quality. The process still follows the red-green-refactor that is the essence of TDD. The major difference is the definition level. While until this moment, we were mostly working at units level, this time we'll move a bit higher and apply TDD through functional and integration tests.

Our frameworks of choice will be JBehave and Selenide.

The following topics will be covered in this chapter:

  • The different specifications
  • Behavior-driven development (BDD)
  • The Books Store BDD story
  • JBehave

Different specifications

We already mentioned that one of the benefits of TDD is executable documentation that is always up to date. However, documentation obtained through unit tests is often not enough. When working at such a low level, we get insights into details; however, it is all too easy to miss the big picture. If, for example, you were to inspect specifications that we created for the Tic-Tac-Toe game, you might easily miss the point of the application. You would understand what each unit does and how it interoperates with other units, but would have a hard time grasping the idea behind it. To be precise, you would understand that unit X does Y and communicates with Z; however, the functional documentation and the idea behind it would be, at best, hard to find.

The same can be said for development. Before we start working on specifications in the form of unit tests, we need to get a bigger picture. Throughout this book, you were presented with requirements that we used for writing specifications that resulted in their implementation. Those requirements were later on discarded; they are nowhere to be seen. We did not put them to the repository, nor did we use them to validate the result of our work.

Documentation

In many organizations that we worked with, the documentation was created for the wrong reasons. The management tends to think that documentation is somehow related to project success; that without a lot of (often short-lived) documentation, the project will fail. Thus, we are asked to spend a lot of time planning, answering questions, and filling in questionnaires that are often designed not to help the project but to provide an illusion that everything is under control. Someone's existence is often justified with documentation (the result of my work is this document). It also serves as a reassurance that everything is going as planned (there is an Excel sheet that states that we are on schedule). However, by far the most common reason for the creation of documentation is a process that simply states that certain documents need to be created. We might question the value of those documents; however, since the process is sacred, they need to be produced.

Not only that documentation might be created for the wrong reasons and might not provide enough value, but, as is often the case, it might also do a lot of damage. If we created the documentation, it is natural that we trust it. However, what happens if that documentation is not up to date? The requirements are changing, bugs are getting fixed, new functionalities are being developed, and some are being removed. If given enough time, all traditional documentation becomes obsolete. The sheer task of updating documentation with every change we make to the code is so big and complex that, sooner or later, we must face the fact that static documents do not reflect the reality. If we are putting our trust into something that is not accurate, our development is based on wrong assumptions.

The only accurate documentation is our code. The code is what we develop, what we deploy, and is the only source that truthfully represents our application. However, code is not readable by everyone involved with the project. Besides coders, we might work with managers, testers, business people, end users, and so on.

In search of a better way to define what would constitute better documentation, let us explore a bit further who are the potential documentation consumers. For the sake of simplicity, we'll divide them into coders (those capable of reading and understanding code) and non-coders (everyone else).

Documentation for coders

Developers work with code and, since we established that code is the most accurate documentation, there is no reason to not utilize it. If you want to understand what some method does, take a look at the code of that method. Having doubt about what some class does? Take a look at that class. Having trouble understanding a piece of code? We have a problem! However, the problem is not that the documentation is missing, but that the code itself is not written well.

Looking at the code to understand the code is still often not enough. Even though you might understand what the code does, the purpose of that code might not be so obvious. Why was it written in the first place?

That's where specifications come in. Not only are we using them to continuously validate the code, but they also act as executable documentation. They are always up to date because if they aren't, their execution will fail. At the same time, while code itself should be written in a way that is easy to read and understand, specifications provide a much easier and faster way to understand the reasons, logic, and motivations that lead us to write some piece of implementation code.

Using code as documentation does not exclude other types. Quite the contrary, the key is not to avoid using static documentation, but to avoid duplication. When code provides the necessary details, use it before anything else. In most cases, this leaves us with higher-level documentation such as an overview, the general purpose of the system, the technologies used, the environment set-up, installation, building, packaging and other types of data that tend to serve more like guidelines and quick-start than detailed information. For those cases, a simple README in markdown format (http://whatismarkdown.com/) tends to the best.

For all code-based documentation, test-driven development is the best.enabler. Until now, we worked only with units (methods). We are yet to see how to apply TDD on a higher level such as, for example, functional specifications. However, before we get there, let's speak about other roles in the team.

Documentation for non-coders

Traditional testers tend to form groups completely separated from developers. This separation leads to increased number of testers who are not familiar with code and assume that their job is to be quality checkers. They are validators at the end of the process and act as a kind of border police that decides what can be deployed and what should be returned back. There is, on the other hand, an increasing number of organizations that are employing testers as integral members of the team with the job of ensuring that quality is built in. This latter group requires testers to be proficient with code. For them, using code as documentation is quite natural. However, what should we do with the first group? What should we do with testers who do not understand the code? Also, it is not only (some) testers that fall into this group. Managers, end-users, business representatives, and so on, are also included. The world is full of people that cannot read and understand code.

We should look for a way to retain the advantages that the executable documentation provides, but write it in a way that can be understood by everyone. Moreover, in the TDD fashion, we should allow everyone to participate in the creation of executable documentation from the very start. We should allow them to define requirements that we'll use to develop applications and, at the same time, to validate the result of that development. We need something that will define what we'll do on a higher level, since low level is already covered with unit tests. To summarize, we need a documentation that can serve as requirements, that can be executed, that can validate our work, and that can be written and understood by everyone.

Say hello to behavior-driven development (BDD).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.206.25