The best React Testing Library is Jest.
It has everything you need to write and run tests. It can scale from 1 test to 10,000 tests due to its ability to run tests in parallel, happily using as many cores as you care to give it. It comes with everything you need to write any type of test you want, from mocking async functions that depend on manipulating time to mocking out methods on a third-party library to isolate what code is actually under test.
It also encourages you to write side-effect free tests. Jest does two things to encourage this: it runs your tests in random order, and it isolates the context in which your test is ran. With these two things combined it is actually harder to write a test that depends on some global state, something you never want to do anyways.
Jest is infinitely configurable. Jest likens itself to a testing platform, breaking itself down into small packages with isolated focuses. Due to that architecture it means you can swap out almost every part of Jest, making it do whatever you want for your testing needs.
On its website Jest asserts that it "makes testing delightful" and that is as close to the truth as you'll get.
React Testing library
While Jest provides the framework and overall structure for writing tests, you should also use React Testing Library (RTL) to make it easy to render and interact with your React components.
Jest is library agnostic, React Testing Library is tailor made for React.
You should use React Testing Library with Jest when writing your React tests.
React Testing Library provides common utilities and helpers for writing React tests, and encourages you to write tests in the same way that users will interact with your components. For example, rather than inspecting the props of a component, you look at the DOM to see if the success checkmark is showing as expected.
There is a slight learning curve to learning RTL's API as the methods are a little unusual due to their user-centric point of view. However once you understand the philosophy and structure behind the APIs they become largely intuitive.
What about Enzyme?
One of the biggest strengths of React Testing Library is that it's implemented on top of the public API provided by React. Which means that as React changes and updates itself, it becomes trivial for RTL to update as well to support the new version of React.
This is not the case for Enzyme. Enzyme delves into React internals, using private APIs that make no stability claims, meaning every new version of React can potentionally break Enzyme functionality, requiring Enzyme to re-implement its behavior using new React internals.
This is currently the case. Enzyme still does not support React 17, meaning every application that uses Enzyme to write tests cannot upgrade to React 17 until Enzyme adds support.
That aside, Enzyme is great if you're looking to write strict unit tests. Enzyme supports manipulating props and states, making it trivial to write tests that check every aspect of a component.
RTL argues that should not be the goal of your tests, and as such doesn't support it. Enzyme lets you decide.
Unit tests, integration tests, or E2E tests?
Jest is primarily geared towards unit tests and integration tests.
Unit tests are written to only test one piece of functionality. In terms of React that means the test is only testing one component.
Integration tests look at how different components work together, or said differently, how they integrate with one another (hence integration tests).
End to end tests (E2E) aim to emulate how a user interacts with your code. From them opening the browser, clicking on a button, that button firing a request to the server, and the server responding with the result. The goal is to test everything.
E2E tests have vastly different requirements then unit and integration tests. For E2E tests you need to use something in addition to Jest.
Cypress for E2E Tests
Cypress is the best library for writing E2E tests.
It provides everything you need to write an E2E test, from spinning up a headless browser to providing an intuitive API for writing your tests.
Its standout feature is its built-in ability to make E2E tests as reliable as possible. If you haven't written an E2E test in the past, then it may surprise you to learn that E2E tests are notoriously flaky, due to all the different moving parts (browser, interacting with the browser, interacting with the UI, spinning up a server). In the past you would have to write all these helper methods and wrappers around your E2E tests to remove flakiness: retry interactions, wait for items on the page to appear or dissapear.
However Cypress does all of that for you, by default. Out of the box Cypress is the most reliable E2E testing suite you can use to write E2E tests.
Also good: Mocha
Mocha has been around for a long time. It's built for writing node.js tests but it's just as good at running UI tests, especially when you couple React Testing Library to it.
For the longest time a big differentiator between Mocha and Jest was the inability for Mocha to run tests in parallel. That's no longer true, with Mocha 8 bringing support for parallel test runs.
However compared to Jest, Mocha is a lightweight framework, not providing much beyond a test framework and a test runner.
If you don't want or need everything that Jest provides, then Mocha is a fine alternative.