Which is Better JavaScript Testing Utilities?
enzyme vs jest-dom vs chai-dom vs react-testing-library
1 Year
enzymejest-domchai-domreact-testing-librarySimilar Packages:
What's JavaScript Testing Utilities?

JavaScript testing utilities provide developers with tools to ensure their code behaves as expected. They facilitate unit testing, integration testing, and end-to-end testing, which are crucial for maintaining code quality and reliability. These packages offer various features tailored to different testing needs, particularly in the context of React applications. Choosing the right testing utility can significantly impact the efficiency of the testing process and the overall quality of the application.

NPM Package Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
enzyme1,711,31719,952-2815 years agoMIT
jest-dom95,045---5 years ago-
chai-dom65,0097567.3 kB15a year agoMIT
react-testing-library44,604---5 years ago-
Feature Comparison: enzyme vs jest-dom vs chai-dom vs react-testing-library

Assertion Syntax

  • enzyme: Enzyme provides a flexible API for testing React components, allowing assertions to be made on the rendered output. However, it relies on the standard Chai or Jest assertion libraries, which may require additional setup for custom assertions.
  • jest-dom: Jest-Dom offers a set of custom matchers that work seamlessly with Jest, providing a more intuitive syntax for asserting DOM states, such as 'toBeInTheDocument' or 'toHaveTextContent', making tests more readable and expressive.
  • chai-dom: Chai-Dom extends Chai's assertion library with DOM-specific assertions, allowing for more expressive tests such as checking if an element is visible or has a specific class. This makes tests easier to read and understand, improving maintainability.
  • react-testing-library: React Testing Library encourages assertions that reflect user interactions, focusing on queries like 'getByText' or 'queryByRole', promoting tests that are more aligned with how users actually use the application.

Rendering Options

  • enzyme: Enzyme offers multiple rendering options: shallow rendering for unit tests, full DOM rendering for integration tests, and static rendering for snapshot tests, giving flexibility in how components are tested.
  • jest-dom: Jest-Dom does not handle rendering; it is designed to work with Jest's rendering capabilities, allowing you to use it alongside React Testing Library or Enzyme for rendering components before making assertions.
  • chai-dom: Chai-Dom does not provide rendering capabilities; it is solely an assertion library that enhances Chai's functionality for DOM elements, requiring integration with other libraries for rendering.
  • react-testing-library: React Testing Library focuses on rendering components in a way that simulates user interaction, promoting best practices by encouraging tests that prioritize user experience over implementation details.

Learning Curve

  • enzyme: Enzyme has a moderate learning curve, especially for developers new to React testing. Understanding its API and rendering methods may take some time, but it offers comprehensive documentation and examples to aid learning.
  • jest-dom: Jest-Dom is simple to learn, especially for those already using Jest. Its matchers are intuitive and easy to understand, making it a quick addition to your testing toolkit without a steep learning curve.
  • chai-dom: Chai-Dom is easy to learn for those already familiar with Chai, as it builds upon existing knowledge of assertions while adding DOM-specific capabilities. Its documentation is straightforward, making it accessible for beginners.
  • react-testing-library: React Testing Library has a gentle learning curve, particularly for those familiar with React. Its focus on user-centric testing makes it easier to grasp, and its documentation emphasizes best practices.

Community and Ecosystem

  • enzyme: Enzyme has a strong community and is widely used in the React ecosystem, but it has faced some challenges with updates and compatibility with the latest React features, leading to discussions about its future.
  • jest-dom: Jest-Dom is part of the Jest ecosystem, which is one of the most popular testing frameworks in the JavaScript community. Its integration with Jest ensures strong community support and regular updates.
  • chai-dom: Chai-Dom benefits from the larger Chai community, which provides extensive resources and plugins. However, its focus is narrower, primarily enhancing Chai's capabilities for DOM assertions.
  • react-testing-library: React Testing Library has gained significant traction in the React community, with a strong emphasis on best practices and user-centric testing. It is actively maintained and widely adopted, ensuring robust community support.

Integration

  • enzyme: Enzyme can be integrated with various assertion libraries, including Chai and Jest, offering flexibility in how tests are written, but it may require additional configuration to work optimally with different setups.
  • jest-dom: Jest-Dom is designed to work exclusively with Jest, enhancing its assertion capabilities for DOM elements. It is easy to integrate into existing Jest test suites, making it a natural choice for projects already using Jest.
  • chai-dom: Chai-Dom integrates seamlessly with Chai and can be used alongside other testing libraries, but it requires additional setup for rendering components, as it does not provide its own rendering capabilities.
  • react-testing-library: React Testing Library integrates well with Jest and other testing frameworks, promoting a user-centric approach to testing React components. It encourages best practices and is designed to work smoothly with modern React features.
How to Choose: enzyme vs jest-dom vs chai-dom vs react-testing-library
  • enzyme: Choose Enzyme if you need a powerful testing utility specifically for React components, allowing for shallow rendering, full DOM rendering, and static rendering, which makes it easier to test component behavior and lifecycle methods.
  • jest-dom: Choose Jest-Dom if you are using Jest as your testing framework and want to enhance your assertions with custom matchers that make it easier to test the state of the DOM, providing a more intuitive way to write tests for user interfaces.
  • chai-dom: Choose Chai-Dom if you are already using Chai for assertions and need to extend its capabilities to include DOM-specific assertions, enhancing your tests with more readable and expressive syntax.
  • react-testing-library: Choose React Testing Library if you want to focus on testing components in a way that resembles how users interact with them, promoting better testing practices by encouraging you to test the component's behavior rather than its implementation details.
README for enzyme

Enzyme

Join the chat at https://gitter.im/airbnb/enzyme

npm Version License Build Status Coverage Status

Enzyme 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.

Upgrading from Enzyme 2.x or React < 16

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.

Installation

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() });

3rd Party Adapters

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)|

Running Enzyme Tests

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:

Using Enzyme with Mocha

Using Enzyme with Karma

Using Enzyme with Browserify

Using Enzyme with SystemJS

Using Enzyme with Webpack

Using Enzyme with JSDOM

Using Enzyme with React Native

Using Enzyme with Jest

Using Enzyme with Lab

Using Enzyme with Tape and AVA

Basic Usage

Shallow Rendering

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

Full DOM Rendering

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

Static Rendered Markup

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

React Hooks support

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() wrap

If 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(/* ... */);

Future

Enzyme Future

Contributing

See the Contributors Guide

In the wild

Organizations and projects using enzyme can list themselves here.

License

MIT