Use Enzyme & Jest Snapshots to Test data-testid Attributes in React Components

Asís García
Trabe
Published in
3 min readOct 12, 2020
Photo by Jens Johnsson on Unsplash

Adding a data-testid attribute as a way to identify a DOM node for testing purposes, is a common tool recommended by many (testing-library, cypress) as it decouples the DOM structure of your application from its tests.

When working with React, setting a data-testid on a DOM node (a host component) is easy: you just… set it 😅

Defining test ids for your components

React is all about components, right? So, how do you set a data-testid inside a DOM node rendered by a component? Well, you have to pass a prop. You can name the prop data-testid, but then you’ll not be able to destructure that prop as a parameter of your component, so my advice is to name it testId.

That is a pretty silly component, rendering just a div with its test id. Most of the time you create components with a more complex structure. The problem is, if you want to refer to different parts of that structure through a test id, how do you do it?

There are two options:

  1. You pass a “map” of test ids in the testId prop, instead of a string. You use different keys for each part of the component you want to identify, and the value associated with each key as a data-testid for each DOM node.
  2. You “derive” new test ids from the one provided via the testId prop.

The first option is more explicit, but also more cumbersome to use. Think of a really complex component, like a data grid with many columns, rows and controls. In that case you may need to specify dozens of test ids in order to access every part of such a component.

The second option gives the “user” of your component less control, but it’s much easier to use: you just give the whole component a test id and derive from it different data-testid attributes for each part:

Testing your test ids

This is kind of meta, but if you’re developing components for others to use, you might want to test that you are setting the right test ids for your component.

Using selectors

One option is to use selectors: you find each node using a [data-testid=”the-id”] selector and assert that it exists. This is a simple option, and it lets you test that each test id is in place, but it tells you nothing about where you are setting those ids.

Using snapshots

Using a snapshot lets you check that every test id is being set, and it also lets you know on which node you set each test id. The problem is, snapshots are quite noisy, and you might have a hard time finding the test ids in the middle of all the other stuff.

Using custom snapshots

You can overcome the noise customizing the value to snapshot.

In the following snippet we define a keepTestId function which strips everything from the JSON representation of an enzyme wrapper, except for the data-testid, class and className props:

You can use it to test the “test id structure” of your components. We keep the class attributes so it’s easier to identify each node in the snapshot, specially when the component is complex, but you could choose to remove them and just keep the data-testid.

Given our Accordion component, we could test its structure with a test like this:

That will result in the following snapshot being written:

As you can see, the output is barebone. Say we change the component to wrap the details inside a h1 element:

The test ids snapshot will stay the same.

Snapshot testing has a bad reputation for leading to brittle tests, and for snapshots being easily overlooked when doing code reviews, but I find that in cases like this one, where the “spatial” information is important (I want to know where I set the test ids), they are the way to go. Specially if you adapt them to your specific needs, as we’ve seen in this story.

--

--