Both Enzyme and React Testing Library are popular tools for testing React applications, but they have different philosophies. Enzyme focuses on testing component internals and implementation details, allowing developers to manipulate component state and props directly. React Testing Library encourages testing components the way users would interact with them, focusing on accessibility and user behavior rather than implementation details.
Enzyme provides a more comprehensive set of utility functions for testing React components, including shallow rendering, full rendering, and static rendering. React-testing-library focuses on providing a simple and intuitive API for testing React components, with a focus on encouraging good testing practices.
Both packages support TypeScript, with enzyme requiring a separate @types/enzyme package and react-testing-library including TypeScript definitions out of the box.
Both packages are compatible with modern browsers, including Chrome, Firefox, and Edge.
Enzyme has a larger dependency tree, including dependencies like cheerio and jsdom. React-testing-library has a smaller dependency tree, with fewer dependencies.
React-testing-library is generally faster and more lightweight than enzyme, due to its simpler architecture and fewer dependencies.
Both packages are compatible with React, with enzyme also supporting other frameworks like React Native.
React-testing-library has a more active community, with more contributors and a faster pace of development.
Both packages have high-quality documentation, with react-testing-library's documentation being more comprehensive and easier to navigate.
React-testing-library is maintained by the React team, ensuring a high level of maintenance and support. Enzyme is maintained by Airbnb, with a slightly slower pace of development.
1import React from 'react';
2import { shallow } from 'enzyme';
3import MyComponent from './MyComponent';
4
5const wrapper = shallow(<MyComponent />);
6expect(wrapper.find('div').length).toBe(1);
This example shows how to use enzyme's shallow rendering function to test a React component.
1import React from 'react';
2import { render, fireEvent, waitFor } from '@testing-library/react';
3import MyComponent from './MyComponent';
4
5const { getByText } = render(<MyComponent />);
6fireEvent.click(getByText('Click me'));
7waitFor(() => getByText('Button clicked'));
This example shows how to use react-testing-library's render function to test a React component, along with the fireEvent and waitFor utilities.
React-testing-library is a more modern and lightweight testing library, with a stronger focus on good testing practices. Enzyme is a more comprehensive testing library, with a larger set of utility functions.
A companion package to React Testing Library that adds custom DOM element matchers for Jest. It helps you write clearer tests by providing simple ways to check if elements have certain classes, attributes, or text content.
Works perfectly with React Testing Library and makes DOM testing much easier. It's like having extra tools to check what's on your webpage during tests.
Testing UtilitiesA special testing tool just for React hooks. It lets you test custom hooks without needing to create full components.
Perfect alternative when you're specifically testing React hooks. Much simpler than trying to test hooks with Enzyme or regular React Testing Library.
Testing FrameworkA lightweight testing utility that helps you test React components. It provides simple functions to check what's showing up on the screen in your tests.
Good for beginners who find Enzyme or React Testing Library too complex. It has fewer features but is easier to learn and use.
Testing FrameworkThe Vue.js equivalent of Enzyme/React Testing Library. It helps you test Vue components in a similar way to how you'd test React components.
Perfect alternative if you're switching from React to Vue.js. It follows similar testing patterns but is made specifically for Vue components.
Testing FrameworkA complete testing tool that lets you test your whole website like a real user would. You can click buttons, fill forms, and see everything happen in a real browser.
While different from Enzyme/RTL, it's becoming very popular because it tests your app more realistically. It can do everything from unit tests to full website testing.
End-to-End TestingEnzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output. You can also manipulate, traverse, and in some ways simulate runtime given the output.
Enzyme's API is meant to be intuitive and flexible by mimicking jQuery's API for DOM manipulation and traversal.
Are you here to check whether or not Enzyme is compatible with React 16? Are you currently using Enzyme 2.x? Great! Check out our migration guide for help moving on to Enzyme v3 where React 16 is supported.
To get started with enzyme, you can simply install it via npm. You will need to install enzyme along with an Adapter corresponding to the version of react (or other UI Component library) you are using. For instance, if you are using enzyme with React 16, you can run:
npm i --save-dev enzyme enzyme-adapter-react-16
Each adapter may have additional peer dependencies which you will need to install as well. For instance,
enzyme-adapter-react-16
has peer dependencies on react
and react-dom
.
At the moment, Enzyme has adapters that provide compatibility with React 16.x
, React 15.x
,
React 0.14.x
and React 0.13.x
.
The following adapters are officially provided by enzyme, and have the following compatibility with React:
| Enzyme Adapter Package | React semver compatibility |
| --- | --- |
| enzyme-adapter-react-16
| ^16.4.0-0
|
| enzyme-adapter-react-16.3
| ~16.3.0-0
|
| enzyme-adapter-react-16.2
| ~16.2
|
| enzyme-adapter-react-16.1
| ~16.0.0-0 \|\| ~16.1
|
| enzyme-adapter-react-15
| ^15.5.0
|
| enzyme-adapter-react-15.4
| 15.0.0-0 - 15.4.x
|
| enzyme-adapter-react-14
| ^0.14.0
|
| enzyme-adapter-react-13
| ^0.13.0
|
Finally, you need to configure enzyme to use the adapter you want it to use. To do this, you can use
the top level configure(...)
API.
import Enzyme from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; Enzyme.configure({ adapter: new Adapter() });
It is possible for the community to create additional (non-official) adapters that will make enzyme work with other libraries. If you have made one and it's not included in the list below, feel free to make a PR to this README and add a link to it! The known 3rd party adapters are:
| Adapter Package | For Library | Status |
| --- | --- | --- |
| enzyme-adapter-preact-pure
| preact
| (stable) |
|enzyme-adapter-inferno
|inferno
|(work in progress)|
Enzyme is unopinionated regarding which test runner or assertion library you use, and should be compatible with all major test runners and assertion libraries out there. The documentation and examples for enzyme use mocha and chai, but you should be able to extrapolate to your framework of choice.
If you are interested in using enzyme with custom assertions and convenience functions for testing your React components, you can consider using:
chai-enzyme
with Mocha/Chai.jasmine-enzyme
with Jasmine.jest-enzyme
with Jest.should-enzyme
for should.js.expect-enzyme
for expect.Using Enzyme with React Native
Using Enzyme with Tape and AVA
import React from 'react'; import { expect } from 'chai'; import { shallow } from 'enzyme'; import sinon from 'sinon'; import MyComponent from './MyComponent'; import Foo from './Foo'; describe('<MyComponent />', () => { it('renders three <Foo /> components', () => { const wrapper = shallow(<MyComponent />); expect(wrapper.find(Foo)).to.have.lengthOf(3); }); it('renders an `.icon-star`', () => { const wrapper = shallow(<MyComponent />); expect(wrapper.find('.icon-star')).to.have.lengthOf(1); }); it('renders children when passed in', () => { const wrapper = shallow(( <MyComponent> <div className="unique" /> </MyComponent> )); expect(wrapper.contains(<div className="unique" />)).to.equal(true); }); it('simulates click events', () => { const onButtonClick = sinon.spy(); const wrapper = shallow(<Foo onButtonClick={onButtonClick} />); wrapper.find('button').simulate('click'); expect(onButtonClick).to.have.property('callCount', 1); }); });
Read the full API Documentation
import React from 'react'; import sinon from 'sinon'; import { expect } from 'chai'; import { mount } from 'enzyme'; import Foo from './Foo'; describe('<Foo />', () => { it('allows us to set props', () => { const wrapper = mount(<Foo bar="baz" />); expect(wrapper.props().bar).to.equal('baz'); wrapper.setProps({ bar: 'foo' }); expect(wrapper.props().bar).to.equal('foo'); }); it('simulates click events', () => { const onButtonClick = sinon.spy(); const wrapper = mount(( <Foo onButtonClick={onButtonClick} /> )); wrapper.find('button').simulate('click'); expect(onButtonClick).to.have.property('callCount', 1); }); it('calls componentDidMount', () => { sinon.spy(Foo.prototype, 'componentDidMount'); const wrapper = mount(<Foo />); expect(Foo.prototype.componentDidMount).to.have.property('callCount', 1); Foo.prototype.componentDidMount.restore(); }); });
Read the full API Documentation
import React from 'react'; import { expect } from 'chai'; import { render } from 'enzyme'; import Foo from './Foo'; describe('<Foo />', () => { it('renders three `.foo-bar`s', () => { const wrapper = render(<Foo />); expect(wrapper.find('.foo-bar')).to.have.lengthOf(3); }); it('renders the title', () => { const wrapper = render(<Foo title="unique" />); expect(wrapper.text()).to.contain('unique'); }); });
Read the full API Documentation
Enzyme supports react hooks with some limitations in .shallow()
due to upstream issues in React's shallow renderer:
useEffect()
and useLayoutEffect()
don't get called in the React shallow renderer. Related issue
useCallback()
doesn't memoize callback in React shallow renderer. Related issue
ReactTestUtils.act()
wrapIf you're using React 16.8+ and .mount()
, Enzyme will wrap apis including .simulate()
, .setProps()
, .setContext()
, .invoke()
with ReactTestUtils.act()
so you don't need to manually wrap it.
A common pattern to trigger handlers with .act()
and assert is:
const wrapper = mount(<SomeComponent />); act(() => wrapper.prop('handler')()); wrapper.update(); expect(/* ... */);
We cannot wrap the result of .prop()
(or .props()
) with .act()
in Enzyme internally since it will break the equality of the returned value.
However, you could use .invoke()
to simplify the code:
const wrapper = mount(<SomeComponent />); wrapper.invoke('handler')(); expect(/* ... */);
See the Contributors Guide
Organizations and projects using enzyme
can list themselves here.