19
Understanding React Testing Library
Who doesn't love React Testing Library? If you write tests for React, you probably use it a lot. People even like to call it the successor of Enzyme, but React Testing Library and Enzyme are nothing alike. While React Testing Library already gives you superpowers — understanding its principles will help you write much better tests for your React UIs. I promise you will gain something out of this short read.
The user lives in the heart of the principles of React Testing Library. Everything that the library does, revolves around the user.
Good UI tests give you confidence that your components work for your users. They verify that your components look right and behave the right way. How you implement it behind the scenes is not important for the user. This is why good UI tests should never rely on the implementation details of a UI component.
If your tests rely on how a given component is implemented, those test cases will break when you re-factor your codebase. This makes your tests extremely hard to maintain and will slow you down. You don't want that.
Remember — you want your UI tests to verify the end result, not the internal implementation. This is the pivotal idea behind React Testing Library.
The more your tests resemble the way your software is used, the more confidence they can give you.
— testing-library.com
Enzyme gives you access to the component's state, props, children, etc. React Testing Library doesn't do that. It gives you the DOM instead because that's what your users will have. If your tests are good enough, you will never have to explicitly access the component's state or props to make any assertions. Just use the DOM.
Passing a backgroundColor
prop to a <Button />
? Render the button to the DOM and verify that the rendered button's background color. Don't access the props of the component and make an assertion. Make a visual assertion.
it('should apply the background color properly', async () => {
const bgColor = '#ccc222';
const text= 'hi';
const { getByText} = render(<Button backgroundColor={bgColor} text={text} />);
const button = getByText(text);
expect(button.style.backgroundColor).toEqual(bgColor);
})
Want to test the loading state of a component? Make an assertion on the way the component looks when it is loading. Don't verify whether the loading
state of the component is true
.
it('should render correctly while loading', async () => {
const src= '#';
const altText = 'hi';
const { getByAltText } = render(<Image src={src} alt={altText} />);
const image = getByAltText(altText);
expect(image.src).toEqual(loadingSrc);
// Note: you need to write fireEvent.load(image) in order to complete loading the image.
// Since we have not done that, the image is still 'loading'.
})
React Testing Library is inspired by its love for great user experience. If you are writing good tests using React Testing Library, you can be assured that the experience you ship to your users will be what you wanted. It gives you that much-needed confidence when pushing to production and let me tell you, it feels good. Anything that relieves you of some stress is a blessing and React Testing Library is definitely one.
What about the developer experience? Well, React Testing Library excels at that, too. The syntax is extremely intuitive. You don't have to know any intricacies in order to get up and running. The querying methods like getByText
, getByAltText
, etc allow developers to query the DOM just like a real end-user. This is so important.
Another massive benefit this library offers to developers is that as long as you only re-factor your component's implementation (not functionality), your tests will not break. I might be repeating myself here, but this will save you a lot of time & headaches. And you will absolutely love it when you refactor the code and nothing breaks. Trust me.
Oh, and the documentation is everything a developer would want from a library. It's perfect.
All in all, React Testing Library helps you ship UIs which are optimized for your end-users. This is something no developer/team would say no to.
I listed a lot of pros of using the library here but if you think there are any cons, comment down below. Let's discuss!
If you gained anything from this article, please follow me here on DEV & on Twitter. I try to balance my Twitter content between knowledge & shitposts. I can promise you will not be disappointed!
19