This is a book about dogma. My dogma. It is a set of principles, practices, and rituals that I have found to be extremely beneficial when building React applications. I try to apply these ideas in my daily work, and I believe in them so much that I take every opportunity to teach others about them. That's why I've written this book: to show you the ideas that have helped me be successful in my own career.
As with any dogma, you are free to make your own mind up about it. There are people who will dislike everything about this book. There are those who will love everything about this book. Yet more people will absorb some things and forget others. All of these are fine. The only thing I ask is that you maintain an open mind while you follow along, and prepare to have your own dogmas challenged.
Test-driven development (TDD) did not originate in the JavaScript community. However, it is perfectly possible to test-drive JavaScript code. And although TDD is not common in the React community, there's no reason why it shouldn't be. In fact, React as a UI platform is a much better fit for TDD than older UI platforms, due to its elegant model of functional components and state.
So what is TDD, and why should you use it? Test-driven development is a process for writing software that involves writing tests, or specifications, before writing any code. Its practitioners follow it because they believe that it helps them build and design higher-quality software with longer life spans, at a lower cost. They believe it offers a mechanism for communicating about design and specification that also doubles up as a rock-solid regression suite. There isn't much empirical data available that proves any of that to be true, so the best you can do is try it out yourself and make your own mind up.
Perhaps most importantly for me, I find that TDD removes the fear of making changes to my software, and that this makes my working days much less stressful than they used to be. I don't worry about introducing bugs or regressions into my work, because the tests protect me from that.
TDD is often taught with 'toy' examples: todo lists, temperature converters, Tic Tac Toe, and so on. This book teaches two real-world applications. Often, the tests get hairy. We will hit many challenging scenarios and come up with solutions for all of them. There are over 450 tests contained within this book, and every one will teach you something.
So, before we begin, a few words of advice.
This is a book about first principles. I believe that learning TDD is about understanding the process in exceptional detail. For that reason, we do not use Enzyme or react-testing-library. Instead, we build our own test helpers. Doing so is not very complicated. The benefit of doing so is a deeper understanding and awareness of what those testing libraries are doing for you. I am not suggesting that you shouldn't use these tools in your daily work—I use them myself—but I am suggesting that going without them is a worthwhile adventure.
This book uses React hooks. These are a new feature in version 16.8, and we also make use of the act function, which became usable in version 16.9. There are no class components in this book. I believe that we should embrace hooks because functional components using hooks are simpler than class components. I embraced hooks during the process of writing this book, which originally started out as a book with class components. Halfway through, we decided to scrap classes entirely and instead, focus on the future.
On that topic, the JavaScript and React landscape changes at such a pace that I can't claim that this book will remain 'current' for very long. That is another reason why I use a first-principles approach. My hope is that when things do change, you'll still be able to use this book and apply what you've learned to those new scenarios.
There are a variety of themes that run throughout the book. The theme of first principles is one I've already mentioned. Another is systematic refactoring, which can come across as rather laborious, but is a cornerstone of TDD and other good design practices. I have provided many examples of that within these pages, but for brevity, I sometimes jump straight to a 'post-refactored' solution. For example, I often choose to extract methods before they are written, whereas in the real world, I would usually write methods inline and only extract when the containing method (or test) becomes too long.
Yet another theme is that of cheating, which you won't find mentioned in many TDD books. It's an acknowledgment that TDD is really a scaffold around which you can build your own rules. Once you've learned and practiced the strict version of TDD for a while, you can learn what cheats you can use to cut corners. What tests won't provide much value in the long run? How can you speed up repetitive tests? So, a cheat is almost like saying you cut a corner in a way that wouldn't be obvious to an observer if they came to look at your code tomorrow. Maybe, for example, you implement three tests at once, rather than one at a time.
Finally, do not for a second think that I wrote this book in a linear sequence from start to finish, or that I knew exactly what order to write the tests. It took a great deal of spiking, trial and error, and making horrendous mistakes before I ended up with the text you have before you. Needless to say, I am now an expert with git rebase.