Chapter 10. Putting It All Together

 

If you always do what you always did, then you will always get what you always got.

 
 --Albert Einstein

We have gone through a lot of theory followed by even more practice. The entire journey was like a speed train and we have hardly had an opportunity to repeat what we learned. There was no time for rest.

The good news is that the time is now. We'll summarize everything we learned and go through TDD best practices. Some of those have already been mentioned, while others will be new.

TDD in a nutshell

Red-green-refactor is the pillar of TDD that wraps it into a short and repeatable cycle. By short, we mean very short. The time dedicated to each phase is often counted in minutes if not seconds. Write a test, see it fail, write just enough amount of implementation code to make the last test pass, run all tests, and pass into the green phase. Once the minimum code is written so that we have safety in the form of passing tests, it is time to refactor the code until it is as good as we're hoping it to be. While in this phase, tests should always pass. Neither new functionalities nor new tests can be introduced while refactoring is in progress. Doing all this in such a short period of time is often scary, or might sound impossible. We hope that, through the practices we did together, your skills have improved as well as your confidence and speed.

While there is a word test in TDD, it is not the main benefit nor objective. TDD is first and foremost a concept of a better way to design our code. On top of that, we end up with tests that should be used to continuously check that the application continues working as expected.

The importance of speed was mentioned often. While part of this is accomplished by us being ever more proficient in TDD, another contributor is test doubles (mocking, stubbing, spying, and so on). With these, we can remove the need for external dependencies such as databases, filesystems, third-party services, and so on.

What are the other benefits of TDD? Documentation is one of them. Since code itself is the only accurate and always up-to-date representation of the applications we're working on, specifications written using TDD (being code as well) is the first place we should turn to when we need to better understand what some piece of code does.

How about design? You noticed how TDD produces code that is designed better. Rather than defining design in advance, with TDD it tends to emerge as we progress from one specification to another. At the same time, code that is easy to test is well-designed code. Tests force us to apply some of the coding best practices.

We also learned that TDD does not need to be practiced only on small units (methods). It can also be used at a much higher level where the focus is on a feature or a behavior that can span multiple methods, classes, or even applications and systems. One of the forms of TDD practiced at such a high level is behavior-driven development (BDD). Unlike TDD, which is based on the unit tests that are done by developers for developers, BDD can be used by almost everyone in your organization. Since it tackles behaviors and it's written in natural (ubiquitous) language, testers, managers, business representatives, and others can participate in its creation and use it as a reference later on.

We defined legacy code as code without tests. We faced some of the challenges legacy code puts in front of us and learned some of the techniques that can be used to make it testable.

With all this in mind, let's go through the TDD best practices.

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

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