Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering React Test-Driven Development

You're reading from   Mastering React Test-Driven Development Build rock-solid, well-tested web apps with React, Redux and GraphQL

Arrow left icon
Product type Paperback
Published in May 2019
Publisher Packt
ISBN-13 9781789133417
Length 496 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Daniel Irvine Daniel Irvine
Author Profile Icon Daniel Irvine
Daniel Irvine
Arrow right icon
View More author details
Toc

Table of Contents (21) Chapters Close

Preface 1. Section 1: First Principles of TDD FREE CHAPTER
2. First Steps with Test-Driven Development 3. Test-driving Data Input with React 4. Exploring Test Doubles 5. Creating a User Interface 6. Section 2: Building a Single-Page Application
7. Humanizing Forms 8. Filtering and Searching Data 9. Test-driving React Router 10. Test-driving Redux 11. Test-driving GraphQL 12. Section 3: Interactivity
13. Building a Logo Interpreter 14. Adding Animation 15. Working with WebSockets 16. Section 4: Acceptance Testing with BDD
17. Writing Your First Acceptance Test 18. Adding Features Guided by Acceptance Tests 19. Understanding TDD in the Wider Testing Landscape 20. Other Books You May Enjoy

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. In this section, I'll detail how to do that.

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.

Keeping up with the book's Git history

This section details all you need to know to work effectively with Git while you're following along with the walk-throughs.

This book is up-to-date with the latest version of React (16.9.0-alpha.0). Packt will update the code repository for future release cycle of React 16.9. Please note this version is not yet production ready. A production release of 16.9 is due for release soon.

Getting started before Chapter 1

The book has an accompanying GitHub repository that contains all of the walk-throughs already implemented in a series of commits. You should clone this to your local development machine as you'll be working within it.

  1. If you have a GitHub account, I suggest you fork the repo so that you can push your work to keep a copy safe. Use the Fork button in the top-right hand corner of the GitHub page to do this.

    The repository is located at https://github.com/PacktPublishing/Mastering-React-Test-Driven-Development.

  2. Once forked, you can then clone this locally by going to a terminal window and typing the following command, replacing <username> with your GitHub username:
git clone [email protected]:<username>/Mastering-React-Test-Driven-Development.git
  1. You may wish to rename the directory to something shorter. On my machine, I've used the name react-tdd.
  2. Change into this directory using the cd command.
  3. Issue the command git checkout tags/starting-point.
  4. Finally, issue the command git checkout -b starting-point-mine to create your own branch from this point.

You're now ready to begin Chapter 1. If the last two commands didn't make any sense, don't panic: I'll explain about tags and branches now.

Working with section tags

There are two separate code bases in this book, and they have their own branches: appointments and spec-logo. Chapter 1 to Chapter 9 cover appointments; Chapter 10 to Chapter 14 cover spec-logo. (Chapter 15 doesn't have any code.)

If you were to check out these branches, you'd get the final, completed versions of the code. This is an interesting sneak peak but it's not how you'll get started.

Instead, many sections have a designated tag, so you can skip to the tag and examine the code at that point. If you see a callout like this:

The Git tag for this section is animation.

...then you can skip to this tag by issuing the following command:

git checkout tags/animation

Once you've output that command, you will be in the detached head state. If you want to begin making changes at that point, you should create a new branch from the tag and work on that. I'd suggest suffixing the name with -mine so that your branches are clearly distinguishable from tags:

git checkout -b animation-mine

You can then commit to this branch. If you have been following along judiciously within your own branch, then you do not need to check out each tag, since you'll already have all of the same code.

However, sometimes you will see a callout like the one that follows, and that means you will need to check out the new tag:

The Git tag for this section is load-available-time-slots. It contains solutions to the exercises from the previous chapter, so if you haven't completed the Exercises section yourself, then you should move to this tag now so that you're up to date.

For more detailed instructions, see the To get the most out of this book section in the Preface.

This type of callout means that the code base now contains additional changes since the last edits covered in the book. It often happens at the start of each chapter when the preceding chapter had exercises, but it also happens when the code base skips ahead with changes that are uninteresting or not related to the content of the book.

When you see this callout, you have two options:

  • You can choose to check out the new tag and start a new branch, starting afresh. In this case, the instructions are the same as before, except now you'd need a different branch name from your existing branch:
git checkout tags/load-available-time-slots
git checkout -b load-available-time-slots-mine
  • You can choose to continue working on the branch you have. This could be because you've been creative and made changes that aren't covered in the book (which I fully support). In this case, git diff and git merge are your friends. You will want to review the changes in the latest tag, and then git merge them in. You may need to handle conflicts:
# to view the differences in the new tag
git diff tags/load-available-time-slots

# to auto-merge those differences into your branch
git merge tags/load-available-time-slots

The second option is not entirely risk free, mainly due to the Exercises section at the end of each chapter.

Solving the exercises

Almost every chapter has an Exercises section at the end. These exercises are designed to give you ideas for how you continue practicing what you've learned. They have already been solved in the GitHub repository so you can see how I've solved them. The next chapter always starts from the point where I've solved the exercises.

Should you choose to solve the exercises—which I encourage you to do—then the likelihood is that you'll have solved them in a different way than I would have. Unfortunately, this might leave you in merge hell when you begin the next chapter.

If you find yourself in this situation, I suggest you first study the differences between your approach and mine. Think about how they differ and the relative merits of each. (Do not think that mine will be any better than yours.)

Then, ensuring you've committed and successfully stored your code, move to a new tag and a new branch, starting again.

In other words, be pragmatic and don't spend an inordinate amount of time fighting the system. It's better to keep moving and not get stuck or frustrated.

Pro tip: always keep your exercise solutions in a separate commit. When you move on to the next chapter, branch from your pre-Exercises commit and merge in the official exercise solutions instead.

Debugging when things go wrong

Should you get stuck, or your tests fail in a way that you weren't expecting, feel free to launch the application and see what the console is telling you. Add in console.log statements to help you debug.

The best defense against getting stuck is committing early and often. Any time you have a working feature, commit it!

Download the example code files

In addition to the GitHub repository, if you prefer you can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.

You can download the code files by following these steps:

  1. Log in or register at www.packt.com.
  2. Select the SUPPORT tab.
  3. Click on Code Downloads & Errata.
  4. Enter the name of the book in the Search box and follow the onscreen instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

  • WinRAR/7-Zip for Windows
  • Zipeg/iZip/UnRarX for Mac
  • 7-Zip/PeaZip for Linux

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

Conventions used

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

CodeInText: Indicates code words in text, React component names, test names, directory names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "In test/domManipulators.js, add the following new property to the return object of createContainer."

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

$ mkdir css
$ cd css

Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "The final test for the Undo button is to check that it dispatches an UNDO action when it is clicked."

Warnings or important notes appear like this.
Tips and tricks appear like this.

Understanding code snippets

A block of code is set as follows:

const handleBlur = ({ target }) => {
const result = required(target.value);
setValidationErrors({
...validationErrors,
firstName: result
});
};

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:

const handleBlur = ({ target }) => {
const validators = {
firstName: required
};
const result = validators[target.name](target.value);
setValidationErrors({
...validationErrors,
[target.name]: result
});
};

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);
...
}

JavaScript syntax

As much as possible, the book aims to be consistent with its approach to syntax. There are some choices that may be contentious but I hope that they won’t put you off reading. For example, I use semi-colons throughout. If you’d prefer to not use semi-colons, please feel free to ignore them in your own code.

Prettier

I have used Prettier to format code samples, and its configuration is set within package.json in each of the appointments and spec-logo projects. Here it is:

"prettier": {
"singleQuote": true,
"printWidth": 67,
"jsxBracketSameLine": true
}

Feel free to change this to your own configuration and reformat files as you see fit. The line width of 67 characters is particularly short but ensures that, for the most part, code snippets do not suffer from line breaks.

The one place this is not true is with test descriptions:

it('passes from and to times through to appointments when retrieving appointments', async () => {

In these cases, although the text is printed over two lines, you should enter it on one line only. If you are copy and pasting code samples from the electronic version of this book, you’ll need to remove the extra line breaks that are inserted by your editor.

Arrow functions

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 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 and the return keyword is used to denote when the function returns:

const dailyTimeSlots = (salonOpensAt, salonClosesAt) => {
const totalSlots = (salonClosesAt - salonOpensAt) * 2;
const startTime = new Date().setHours(salonOpensAt, 0, 0, 0);
const increment = 30 * 60 * 1000;
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
});

Object and array destructuring

This book makes liberal use of destructuring techniques in an effort 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 = ({ target: { value, name } }) => {
const target = event.target;
const value = target.value;
const name = target.name;
...
};

Return values can also be destructured in the same way. More frequently, you’ll see return values destructured. This happens with the useState hook:

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

This is equivalent to:

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

Directory structure

Finally, both code bases suffer from a distinct lack of civilized directory structure. I hope this isn’t an issue for you; I just didn’t want to spend time discussing building directories and moving files when it isn’t the focus of the book.

lock icon The rest of the chapter is locked
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.
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 $19.99/month. Cancel anytime
Banner background image