1. Chapters
  2. What are the different types of tests we use in React?

Master useEffect in a single afternoon - 50% off!
2 days 11 hours 1 mins 8 secs

Chapters

What are the different types of tests we use in React?

When we write tests for our React components, we typically only use three types of tests: Unit tests, Integration tests, and End-to-end (E2E) tests.

I'll also cover snapshot testing and visual regression testing, although I consider them to be forms of unit testing.

Unit Testing

Unit testing involves testing a unit (or chunk of code) in isolation, to figure out whether it does what we expect. In React, typically the "unit" refers to a utility function, function component, or class component.

Here's an example of a unit we would typically write unit tests for :

function convertScoreToColour(score) {
const BAD = '#FF0000';
const AVERAGE = '#FFFF00';
const GOOD = '#00FF00';
if (score < 50) {
return BAD;
} else if (score < 90) {
return AVERAGE;
} else return GOOD;
}

Your actual tests would then look like this:

describe('convertScoreToColour', () => {
test('Numbers < 50 return the BAD colour', () => {
let output = convertScoreToColour(50);
expect(output).toBe('#FF0000');
});
test('Numbers > 50 but < 90 return the AVERAGE colour', () => {
let output = convertScoreToColour(75);
expect(output).toBe('#FFFF00');
});
test('All other numbers return the GOOD colour', () => {
let output = convertScoreToColour(92);
expect(output).toBe('#00FF00');
});
});

Despite this being a contrived example (that could use some refactoring), there's quite a bit of benefit you can already get from testing a function in this way.

For example, if we expect our function to only handle numbers less than 100, we could write a test to check what happens when the number is greater than 100:

test('Numbers > 100 return nothing', () => {
let output = convertScoreToColour(101);
expect(output).toBe('');
});

This test example would fail (the code we wrote would return the good colour in this case), so you'd have to now update the function to match the behaviour you expect in your tests.

(PS: This example, where we wrote our test for numbers greater than 100 before writing code is a form of test-driven development, which we'll cover in a later chapter)

In earlier versions of React, before React Testing Library became popular, we would test React components in this way too - load up a component, call a function with certain inputs, and check that the output matches what we expect.

Over time, developers found that tests like these didn't give us much confidence when using several components together, so we started focusing more on integration testing.

Integration Testing

It helps to think of integration testing like a bigger unit test, except the unit you're testing is the combination of several smaller components.

More concretely, instead of just testing a Button component, or a TextField component by themselves, an integration test ensures that several TextField components placed next to a Button component, within a Form component, behave as we expect.

See the first chapter - How do I get started testing? for a practical example of integration testing a form.

End to End Testing

End-to-end (E2E) tests involve testing a whole user journey, or flow through your app, end-to-end (hence the name).

For example, a typical E2E test may involve logging into your app, clicking through a few screens, creating a few records, viewing them, deleting them, then logging out.

Due to how long E2E tests take to run and develop, we tend to only write E2E tests for what some developers call "happy paths". Happy paths are the journeys your users take through the app when everything goes right - no errors, no warning messages, just checking that performing the correct steps results in the correct response from the system.

Solutions

There are a few solutions in the E2E space worth checking out, particularly Cypress and TestCafé.

There are pros/cons of each tool, depending on what sort of React app you work on. The best way to know which one is for you is to try both, and see if it meets your use case.

Snapshot Testing

Snapshot testing typically means taking a React component, rendering it to string/HTML (so that we have text to save), and saving it as a baseline "good" version. The next time you run your tests, your test runner compares the baseline version against what the React component looks like now. If the two versions are the same, the test passes, otherwise it fails, and the snapshot test needs to either be updated, or you accidentally updated the React component and you need to undo your change.

For a short period of time, the React community considered snapshot testing React components as a "Good Idea". It wasn't until most of our colleagues blindly updated snapshots every time they changed that we realized perhaps it wasn't such a good idea after all.

In a React app of hundreds of components, "Snapshot Fatigue" became a thing, and when every change to your codebase resulted in a snapshot needing to be updated, people just stopped checking what the changes were.

Visual Regression Testing

Over time, Visual Regression (VR) testing started to emerge as a potential replacement to snapshot testing.

Visual Regression testing is a form of snapshot testing, except instead of comparing two snapshots of text, you compare two different images with the differences highlighted by the visual regression testing service.

Used sparingly (for example, only for your building-block components or component library), visual regression testing is a powerful tool to avoid unintentional changes within your design system or component library.

Solutions

There are a few solutions in the Visual Regression testing space as well - I've personally used Chromatic for a design system in the past, and it saved me hours of manual checks each week.

There's also Percy.

As always, I recommend giving both solutions a trial, and seeing which one you like best.


Now that we know the types of tests to write, let's learn how to make testing a habit in Chapter 5: How to make testing a habit.

Want more articles like this?

I send a single email every two weeks with an article like this one, to help you be a better React developer.

Lots of developers like them, and I'd love to hear what you think as well. You can always unsubscribe.

    Join 910 React developers that have signed up so far.
    See my privacy policy.