This page does not go into detail, but it's for those who have experience in working with Enzyme and are trying to understand how to move to React Testing Library. It also has some helpful information for those who are comparing Enzyme with React Testing Library.
What is React Testing Library?
React Testing Library is part of an open-source project named Testing Library. There are several other helpful tools and libraries in the Testing Library project which you can use to write more useful tests. Besides React Testing Library, here are some other Testing Library's libraries that can help you along the way:
@testing-library/jest-dom: jest-dom provides a set of custom jest matchers that you can use to extend jest. These will make your tests more declarative, clear to read, and to maintain.
@testing-library/user-event: user-event tries to simulate the real events that would happen in the browser as the user interacts with it. For example, userEvent.click(checkbox) would change the state of the checkbox.
Why should I use the React Testing Library?
Enzyme is a good test library. The library and its contributors did so much for the community. Many of the React Testing Library maintainers used and contributed to Enzyme for years before developing and working on React Testing Library. So we want to say, thank you to the contributors of Enzyme!
The primary purpose of the React Testing Library is to give you confidence by
testing your components in the way the user will use them. Users don't care what
happens behind the scenes. They just see and interact with the output. So,
instead of accessing the components' internal API, or evaluating the
you'll get more confidence by writing your tests based on the component output.
React Testing Library aims to solve the problem that many developers face when writing tests with Enzyme which allows (and encourages) developers to test implementation details. Tests which do this ultimately prevent you from modifying and refactoring the component without changing the test. As a result, the tests slowed down your development speed and productivity, since every small change requires rewriting some part of your tests, even if the change you made does not affect the component's output.
Re-writing your tests in React Testing library is worthwhile, because you're trading tests that slow you down for tests that give you more confidence and increase your productivity in the long run.
How to migrate from Enzyme to React Testing Library?
One of the keys to a successful migration is to do it incrementally, by running the two test libraries side by side in the same application and porting Enzyme's tests to React Testing Library one by one. It makes it possible to migrate even large and complex applications without disrupting other businesses because the work can be done collaboratively and spread over some time.
Install React Testing Library
You can check this page for the complete installation and setup guide.
Here is what you should do, first you need to install the React Testing Library:
Import React Testing Library to your test
Let's say we're using Jest (you can use other test frameworks as well), then you just have to import the following modules into your test file:
The test structure is as same as how you would write it in Enzyme
Note: you can also use
itblocks with React Testing Library. React Testing Library doesn't replace Jest, just Enzyme. We recommend
testbecause it helps with this: Avoid Nesting When You're Testing
Basic Enzyme to React Testing Library migration examples
One thing to keep in mind that there's not a one-to-one mapping of Enzyme
features to React Testing Library features. Many Enzyme features result in
inefficient tests. Unfortunately, that means many of the features you're
accustomed to with Enzyme will need to be left behind with Enzyme (no more need
wrapper variable or
wrapper.update() calls, etc.).
React Testing Library has helpful queries which lets you access your component's elements and their properties, and here we'll show typical Enzyme tests with React Testing Library's alternatives.
Let's say we have a
Welcome component, which just shows a welcome message, and
we will have a look at both Enzyme and React Testing Library tests to learn how
we can test this component:
The following component gets a
props and shows a welcome message
h1 element, it also has a text input which users can change to a
different name, and the template updates accordingly. Check the live version on
Test 1: Render the component, and check if the
h1 value is correct
React Testing library
As you see, both are pretty similar, Enzyme's
shallow wrapping doesn't descend
down to sub-components, React Testing Library's
render is more similar to
In React Testing Library, you don't need to assign the
render result to a
variable (wrapper, or etc), and you can simply access the rendered output by
screen. The other good thing to know is that React Testing Library
automatically cleans up the output for each test, so you don't need to call
cleanup on Jest's
The other thing that you might notice is
getByRole which has
heading as its
heading is the accessible role of the
h1 element. You can learn more
about them on queries
documentation page. One of the things people quickly learn to love about Testing
Library is how it encourages you to write more accessible applications (because
if it's not accessible, then it's harder to test).
Test 2: Input texts must have correct value
In the component above, the input text value will be initialized with the
props.lastName values, and we need to check whether the
value is correct or not
React Testing Library
Cool! It's pretty simple and handy, and the tests are clear enough that we don't
need to talk so much about them. But something that you might notice is that the
<form> had a
role="form" attribute, but what is it?
role is one of the accessibility-related attributes that is recommended to use
to improve your web application for people with disabilities. Some elements have
role values and you don't need to set one for them, but some others
<div> do not have one. You could use different approaches to access the
<div> element, but we recommend trying to access elements by their implicit
role to make sure your component is accessible by people with disabilities and
those who are using screen readers. This
section of the query page might
help you to understand better.
Keep in mind that a
<form>must have a
nameattribute in order to have an implicit
form(as required by the specification).
React Testing Library aims to test the component, like how users would, users
see the button, heading, form and other elements by their role, not by their
class, or element tag name. When you use React Testing Library, you
should not try to access the DOM like how you would do by
document.querySelector API (which you can incidentally use in your tests, but
it's not recommended for the reasons stated in this paragraph).
We made some handy query APIs which help you to access the component elements very efficiently, and you can see the list of available queries in detail.
Something else that people have a problem with is that they're not sure which query should they use, luckily we have a great page which explains which query to use, so don't forget to check it out!
If you still have a problem with the React Testing Library's queries, and you're
not sure which query to use, then check out
testing-playground.com and the accompanying
that aims to enable developers to find a better query when writing tests, and it helps you find the best queries to select elements. It allows you to inspect the element hierarchies in the Chrome Developer Tools, and provides you with suggestions on how to select them, while encouraging good testing practices.
using act() and wrapper.update()
In Enzyme, for some asynchronous purposes, you have to call
act() to run your
tests correctly, but in React Testing Library you don't need to use
of the time since it wraps APIs with
act() so you don't need to manually wrap
update() syncs the Enzyme component tree snapshot with the react component
tree, often time you might see
wrapper.update() in Enzyme tests, but React
Testing Library does not need something like that, good for you since you need
to handle fewer things!
Simulate user events
There are two ways to simulate user events, one is a perfect library named
user-event, and the other way
is to use
actually built on top of
fireEvent which simply calls
dispatchEvent on the
element given. However,
user-event is generally recommended because it ensures
that all the events are fired in the correct order for typical user interactions
which helps to ensure your tests resemble the way your software is used.
To use the
@testing-library/user-event module, you first need to install it:
Now you can import it into your test:
To demonstrate how to use
user-event library, imagine we have a component
named Checkbox, and it only shows a checkbox, and we want to simulate the user
event with this component, here is the component:
And here we want to test when a user click on the checkbox, does the value change to “checked”? So, let's see how we write a test for that case:
Nice! With the help of other modules provided by the Testing Library, we can
test our components smoothly! To learn more about the
user-event library, you
can have a look at its
Triggering class methods in tests (
As we already discussed, we are against testing implementation details and things that users are not aware of, and we aim to test and interact with the component like how our users would.
if your test uses instance() or state(), know that you're testing things that the user couldn't possibly know about or even care about, which will take your tests further from giving you confidence that things will work when your user uses them. Kent C. Dodds
If you're unsure how to test something internal within your component, then take a step back and consider: "What does the user do to trigger this code to run." Then make your test do that.