Reader small image

You're reading from  Mastering React Test-Driven Development - Second Edition

Product typeBook
Published inSep 2022
Reading LevelIntermediate
PublisherPackt
ISBN-139781803247120
Edition2nd Edition
Languages
Tools
Right arrow
Author (1)
Daniel Irvine
Daniel Irvine
author image
Daniel Irvine

Daniel Irvine is a UK-based software consultant. He helps businesses simplify their existing codebases and assists dev teams in improving the quality of their software using eXtreme programming (XP) practices. He has been coaching developers for many years and co-founded the Queer Code London meetup.
Read more about Daniel Irvine

Right arrow

Preface

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 user interface platform is a good fit for TDD because of its elegant model of functional components and state.

So, what is TDD, and why should you use it? TDD 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 lifespans, 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 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: to-do 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 500 tests contained in this book, and each one will teach you something.

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 will not use React Testing Library. Instead, we will build our own test helpers. I am not suggesting that you should avoid these tools in your daily work – I use them myself – but I am suggesting that going without them while you learn is a worthwhile adventure. The benefit of doing so is a deeper understanding and awareness of what those testing libraries are doing for you.

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.

Another theme in this book 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 final, refactored solution. For example, I sometimes 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 the TDD workflow is 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.

In this second edition of the book, I have doubled down on teaching TDD over React features. Beyond updating the code samples to work with React 18, there are few usages of new React features. Instead, the tests have been vastly improved; they are simpler, smaller, and utilize custom Jest matchers (which are themselves test-driven). Readers of the first edition will notice that I’ve changed my approach to component mocks; this edition relies on module mocks via the jest.mock function. The book no longer teaches shallow rendering. There are other smaller changes too, such as the avoidance of the ReactTestUtils.Simulate module. Chapter organization has been improved too, with some of the earlier chapters split up and streamlined. I hope you’ll agree that this edition is leaps and bounds better than the first.

Who this book is for

If you’re a React programmer, this book is for you. I aim to show you how TDD can improve your work.

If you’re already knowledgeable about TDD, I hope there’s still a lot you can learn from comparing your own process with mine.

If you don’t already know React, you will benefit from spending some time running through the Getting Started guide on the React website. That being said, TDD is a wonderful platform for explaining new technologies, and it’s entirely plausible that you’ll be able to pick up React simply by following this book.

What this book covers

Chapter 1, First Steps with Test-Driven Development, introduces Jest and the TDD cycle.

Chapter 2, Rendering Lists and Detail Views, uses the TDD cycle to build a simple page displaying customer information.

Chapter 3, Refactoring the Test Suite, introduces some of the basic ways in which you can simplify tests.

Chapter 4, Test-Driving Data Input with React, covers using React component state to manage the display and saving of text input fields.

Chapter 5, Adding Complex Form Interactions, looks at a more complex form setup with dropdowns and radio buttons.

Chapter 6, Exploring Test Doubles, introduces various types of test doubles that are necessary for testing collaborating objects, and how to use them to test-drive form submission.

Chapter 7, Testing useEffect and Mocking Components, looks at using test doubles to fetch data when components are mounted, and how to use module mocks to block that behavior when testing parent components.

Chapter 8, Building an Application Component, ties everything together with a “root” component that threads together a user journey.

Chapter 9, Form Validation, continues with form building by adding client- and server-side validation and adding an indicator to show that data is being submitted.

Chapter 10, Filtering and Searching Data, shows how to build a search component with some complex interaction requirements, in addition to complex fetch request requirements.

Chapter 11, Test-Driving React Router, introduces the React Router library to simplify navigation within our user journeys.

Chapter 12, Test-Driving Redux, introduces Redux into our application.

Chapter 13, Test-Driving GraphQL, introduces the Relay library to communicate with a GraphQL endpoint that’s provided by our application backend.

Chapter 14, Building a Logo Interpreter, introduces a fun application that we will begin to explore by building out features across both React components and Redux middleware: undo/redo, persisting state across browser sessions with the LocalStorage API, and programmatically managing field focus.

Chapter 15, Adding Animation, covers adding animations to our application using the browser requestAnimationFrame API, all with a test-driven approach.

Chapter 16, Working with WebSockets, adds support for WebSocket communication with our application backend.

Chapter 17, Writing Your First Cucumber Test, introduces Cucumber and Puppeteer, which we will use to build BDD tests for existing functionality.

Chapter 18, Adding Features Guided by Cucumber Tests, integrates acceptance testing into our development process by first building BDD tests with Cucumber, before dropping down to unit tests.

Chapter 19, Understanding TDD in the Wider Testing Landscape, finishes the book by looking at how what you’ve learned fits in with other test and quality practices.

To get the most out of this book

There are two ways to read this book.

The first is to use it as a reference when you are faced with specific testing challenges. Use the index to find what you’re after and move to that page.

The second, and the one I’d recommend starting with, is to follow the walk-throughs step by step, building your own code base as you go along. The companion GitHub repository has a directory for each chapter (such as Chapter01) and then, within that, three directories:

  • Start, which is the starting point for the chapter, and you should start here if you’re following along.
  • Exercises, which is the point at the end of the chapter where the exercises begin. You should start here if you’re attempting the exercises in each chapter. (Note that not every chapter has exercises.)
  • Complete, which contains completed solutions to all the exercises.

You will need to be at least a little proficient with Git; a basic understanding of the branch, checkout, clone, commit, diff, and merge commands should be sufficient.

Take a look at the README.md file in the GitHub repository for more information and instructions on working with the code base.

If you are using the digital version of this book, we advise you to type the code yourself or access the code from the book’s GitHub repository (a link is available in the next section). Doing so will help you avoid any potential errors related to the copying and pasting of code.

Download the example code files

You can download the example code files for this book from GitHub at http://github.com/packtPublishing/Mastering-React-Test-Driven-Development-Second-Edition/. If there’s an update to the code, it will be updated in the GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Download the color images

We also provide a PDF file that has color images of the screenshots and diagrams used in this book. You can download it here: https://packt.link/5dqQx.

Conventions used

There are a number of text conventions used throughout this book.

Code in text: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: “In the first test, change the word appendChild to replaceChildren.”

Bold: Indicates a new term, an important word, or words that you see onscreen. For instance, words in menus or dialog boxes appear in bold. Here is an example: “The presenter clicks the Start sharing button.”

Tips or important notes

Appear like this.

Code snippet conventions

A block of code is set as follows:

it("renders the customer first name", () => {  const customer = { firstName: "Ashley" };  render(<Appointment customer={customer} />);  expect(document.body.textContent).toContain("Ashley");});

There are two important things to know about the code snippets that appear in this book.

The first is that some code samples show modifications to existing sections of code. When this happens, the changed lines appear in bold, and the other lines are simply there to provide context:

export const Appointment = ({ customer }) => (  <div>{customer.firstName}</div>);

The second is that, often, some code samples will skip lines in order to keep the context clear. When this occurs, you’ll see this marked by a line with three dots:

if (!anyErrors(validationResult)) {
  ...
} else {
  setValidationErrors(validationResult); 
} 

Sometimes, this happens for function parameters too:

if (!anyErrors(validationResult)) {
  setSubmitting(true);
  const result = await window.fetch(...);
  setSubmitting(false); 
  ... 
}

Any command-line input or output is written as follows:

npx relay-compiler

JavaScript conventions

The book almost exclusively uses arrow functions for defining functions. The only exceptions are when we write generator functions, which must use the standard function’s syntax. If you’re not familiar with arrow functions, they look like this, which defines a single-argument function named inc:

const inc = arg => arg + 1;

They can appear on one line or be broken into two:

const inc = arg =>
  arg + 1;

Functions that have more than one argument have the arguments wrapped in brackets:

const add = (a, b) => a + b;

If a function has multiple statements, then the body is wrapped in curly braces:

const dailyTimeSlots = (salonOpensAt, salonClosesAt) => {
  ...
  return timeIncrements(totalSlots, startTime, increment);};

If the function returns an object, then that object must be wrapped in brackets so that the runtime doesn’t think it’s executing a block:

setAppointment(appointment => ({  ...appointment,  [name]: value }); 

This book makes liberal use of destructuring techniques to keep the code base as concise as possible. As an example, object destructuring generally happens for function parameters:

const handleSelectBoxChange = (
  { target: { value, name } }
) => {
  ...
}; 

This is equivalent to saying this:

const handleSelectBoxChange = (event) => {
  const target = event.target;
  const value = target.value;
  const name = target.name;
  ...
}; 

Return values can also be destructured in the same way:

const [customer, setCustomer] = useState({});

This is equivalent to the following:

const customerState = useState({});
const customer = customerState[0];
const setCustomer = customerState[1];

Get in touch

Feedback from our readers is always welcome.

General feedback: If you have questions about any aspect of this book, email us at customercare@packtpub.com and mention the book title in the subject of your message.

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata and fill in the form.

Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at copyright@packt.com with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Share Your Thoughts

Once you’ve read Mastering React Test-Driven Development, we’d love to hear your thoughts! Please click here to go straight to the Amazon review page for this book and share your feedback.

Your review is important to us and the tech community and will help us make sure we’re delivering excellent quality content.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Mastering React Test-Driven Development - Second Edition
Published in: Sep 2022Publisher: PacktISBN-13: 9781803247120
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Daniel Irvine

Daniel Irvine is a UK-based software consultant. He helps businesses simplify their existing codebases and assists dev teams in improving the quality of their software using eXtreme programming (XP) practices. He has been coaching developers for many years and co-founded the Queer Code London meetup.
Read more about Daniel Irvine