This MR sets up React Testing Library and makes use of it in one test.
The new integration tests should simulate the way a real user uses the app. They should follow the guiding principle that "The more your tests resemble the way your software is used, the more confidence they can give you."
Here is what it means in practice:
1. Each integration test always renders the whole app, not just a sub-tree.
- When users use the app, they don't just see a part of it; they see the whole thing. One part of the app can impact another part of the app, so it's important to always render everything.
- We're using JSDOM, not a headless browser like we would for end-to-end tests, so rendering the whole app every time does not distinctly slow down the tests. We're also not writing unit tests, so one test can contain multiple preparation steps and multiple expectations in order to cover multiple steps in a user journey -- in other words, we'll never have 10,000 integration tests.
2. Shallow rendering is prohibited.
- When users use the app, the rendering doesn't stop somewhere in the middle of the tree. Again, we want to stay as close to real life as we can.
- Shallow rendering can make tests useless and unreliable -- for instance, if a child component triggers a fetch on mount but we shallow render its parent, nothing will be fetched.
3. Tests never access component instances or refer to React components in any way.
- The tree of components is an implementation detail. It can be refactored without changing any functionality -- for instance, if a component becomes too large, it can be split into multiple components -- and users don't care about this. What matters is the final result: the DOM.
- Similarly, we don't test whether a component's methods have been called or whether a specific Redux action has been dispatched. This is all implementation detail.
4. Querying DOM nodes is done as similarly as possible to how users find elements on the page.
- Users don't access elements by tag name or by class; they look for a heading, for a button with some specific text, for a form label, etc.
- React Testing Library provides a number of queries for this purpose.
ByRoleis the most useful as it looks for elements by semantic (a bit like a screen reader user would).
5. Tests don't fire DOM events; they simulate user actions.
- When a user clicks on a checkbox, a lot more happens than just a
clickevent. This is why this library exists: https://github.com/testing-library/user-event/
This front-end testing guide is a great reference that covers all of these good practices.