The react-testing-library is a very light-weight solution for testing React components. It provides light utility functions on top of react-dom and react-dom/test-utils, in a way that encourages better testing practices. It renders the components and provides utility methods to interact with them. The idea is that you should communicate with your application in the same way a user would.
To answer this question you can ask another question, Why do we write tests in the first place?
There’s one main reason for writing tests and that’s that it gives us confidence in the product that we're shipping confidence that everything’s still working as expected when we make a change to the code base.
Things we don’t like about tests
- Steep Learning curve 📈
- Takes effort to write 😰
- Effort to maintain 🤕
We’ve all been in a situation where we make a change that we think’s fairly benign should be all fine then the tests will fail and you like why and you need to completely rewrite Middle’s to get passed again 🤬
Why is testing implementation details bad?
There are to two distinct reasons that it’s important to avoid testing implementation details. Tests hitch test implementation details:
- Can break when you refactor application code (False-negative)
- May not fail when you break application code (False-positives)
Why not using shallow render?
With shallow rendering, I can refactor my component’s implementation details and my tests break. I can break my application and my tests say everything’s still working 🤔.
What implementation details mean?
Implementation details are things which “users of your code” will not typically use, see, or even know about.
Who is/are the final user?
- The end-user in a browser: View and interact with the component
- The developer user: Renders the component with props
So… what our testing should include then?
- Rendering the component with props (developer user)
- Querying and interacting with the rendered result (end-user)
Our tests should NOT include
Immagine your React component is a black box, you put some props in you get a rendered component out.
Anything inside that black box is implementation details neither the developer user and nor the end-user care about that.
Example of Implementation details:
- Components names
- CSS classes/selectors
- Anything that the users don’t see (Output)!