Apache Superset: Testing and Enzyme to RTL conversion
Tags: testing, react, opensource, webdev
Published: 2022-05-31 17:56:53

Superset uses [Jest](https://jestjs.io/) and [React Testing Library (RTL)](https://testing-library.com/docs/react-testing-library/intro/) to write unit and integration tests. In the past we used [Enzyme](https://enzymejs.github.io/enzyme/), but now that we're currently converting all of our class components to functional components, Enzyme cannot support our testing needs. Since RTL is better for testing functional components, we're converting all of our test files to RTL. This can be quite a learning curve - I've gone through a lot of the process so I'd like to share what I've learned so far.


First and foremost: We have a [Testing Guidelines and Best Practices](https://github.com/apache/superset/wiki/Testing-Guidelines-and-Best-Practices) document that outlines all the code styles we adhere to in our tests. Please use this document as reference when writing your tests.


The main thing you want to keep in mind is the different approach each testing library uses in testing:
- Enzyme is code-focused testing. It tests things in the "back" of the code that the user never sees, such as the props of a component.
- RTL is user-focused testing. All of your tests will rely on things the user can see and do.
  - For example: If there were an Enzyme test that checks the props of a component, you would look for where those props show visually on the component and capture it with RTL.
  - Except for certain things like API mocking, Superset uses fetch-mock for that. [Here's a link to the docs](http://www.wheresrhys.co.uk/fetch-mock/), if you'd like to learn more about how to mock API calls in RTL. You can also look for other already-existing instances of fetch-mock in the codebase to see how it's used in Superset.


The test environment in Superset is getting healthier and easier to work with by the day, and I hope this will inspire you to help contribute to the cause! To wrap this up, I would like to leave you with some good RTL/testing resources:
- In your tests, use these commands to help with debugging:
  - `screen.debug()`
      - This will show you the rendered component in the console when you run the test. You can pass in a captured element if you want to see just that element instead of the whole rendered component.
  - `screen.logTestingPlaygroundURL()`
      - This will give you a link in the console when you run your test. Click this link and it will open an instance of the testing playground displaying your rendered component (or a captured element passed into the function) in the browser. [Check out this link](https://testing-playground.com/) for an example of what that looks like, this is a really cool feature 😁 It would look like this in the code:
```ts
const button = screen.getByRole('button');
screen.debug(button);
screen.logTestingPlaygroundURL(button);
```
- I converted 11 files in [this pull request](https://github.com/apache/superset/pull/16626), feel free to use it as a reference for conversions
- The RTL docs have a good [guide for converting from Enzyme]
(https://testing-library.com/docs/react-testing-library/migrate-from-enzyme/)
- [RTL cheatsheet](https://testing-library.com/docs/react-testing-library/cheatsheet)
- [Jest matchers](https://jestjs.io/docs/expect)
- [jest-dom matchers](https://github.com/testing-library/jest-dom)
- Superset has a very handy [helper file](https://github.com/apache/superset/blob/master/superset-frontend/spec/helpers/testing-library.tsx) for RTL with supercharged functionality for our specific needs.