Difference between enzyme and react-testing-library

Enzyme

Enzyme is a popular testing library from Airbnb. It was released long back, and react official documentation recommends Enzyme to reduce the boilerplate for writing test cases. Enzyme's API is meant to be intuitive and flexible by mimicking jQuery's API for DOM manipulation and traversal.

React Testing Library

React Testing Library - although a very generic name, it is a testing library that aims to solve different use cases than other testing libraries. React testing library forces you to write tests that are not brittle - tests that do not test the implementation but the functionality of the component. It encourages best practices in writing code and making the code testable and testing the right conditions.

Update - React testing library package is now renamed to @testing-library/react

Let's see some of the differences in enzyme vs react-testing-library

Case 1 - Setup

In Enzyme, you need to configure the adapter to make it work with Reac 16. There are other 3rd party adapters available which will enable Enzyme to work with those libraries.

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

In React Testing Library, there is not much setup required. You have to install the react-testing-library npm module and you are good to go.

npm install --save-dev react-testing-library

Case 2 - Concept difference

When you are writing tests in Enzyme, you have methods to check the state property of the class, check what props are being passed to the component. But if you are testing the component using the props and state, it means your tests are brittle. What if someone changes the state variable name tomorrow, then your tests will fail. Even though the functionality of the component is the same, just because the state variable name used in the component is renamed, the tests will fail. This shows the brittleness of the unit tests.

So React Testing Library does not have methods to test the state or props. Instead, it tests the dom, which is what the user is interacting with.

One of the guiding principles of react testing library is

If it relates to rendering components, it deals with DOM nodes rather than component instances, nor should it encourage dealing with component instances.

So you do not have methods where you get the instance of the component, and call the methods of component yourself. Instead, you work on the DOM just like the user. Want to test the async function call to the server? Get the button from the DOM, click on it, mock the API, and check for the result in the DOM.

Case 3 - No forceUpdate() or forcing the re-render of component

In Enzyme, you have the forceUpdate method to re-render the component. If you are spying on some arrow function inside the component (arrow functions inside component is wrong), then you would have to forceUpdate the component.

In React Testing Library, you do not have any such methods. Instead, it tests only using the DOM.

Case 4 - No shallow or deep rendering

In React Testing Library, you do not have direct methods to test the instance of the component. So there is no deep or shallow rendering of the component in React Testing Library.

Case 5 - Opinionated

Enzyme is not an opinionated library. It provides methods to access internals of the component ie the instance methods, state and props of the component. But Enzyme also provides the method to access the DOM of the component.

So by using enzyme, you can choose to test the component internals, or you can choose not to. Enzyme does not enforce any opinion on how you should test the component.

React testing library is opionated library. It only provides you the method to render the componen and access the DOM. It does not provide the method to access the internals of the component intentionally.

Conclusion

Although React Testing Library aims at competing with Enzyme, and encourages you to write testable code and test from the perspective of the user, both of them have use cases. You cannot replace one with another. Sometimes you do need to test the state change or a function inside the component, even though from the user's prespective it may not make sense. In those cases, Enzyme is required to test the instance method. React Testing Library is good for testing the DOM of the component, as it allows you to test just like the user uses it.