A simple and opinionated guide.
We write tests to make sure our application/modules work as intended for the users. To achieve that, we should be able to cover most real-life use cases from our users’ perspectives. Identifying those use cases is a crucial step for realising them into our tests later.
We write both unit and integration tests, but we should put much more emphasis on the latter. Write unit tests for utility functions, and integration tests for parent components at page- or module-level. Unit tests are always nice to have but as the size and complexity of the project grow larger, they can and will become a nuisance to write and maintain, not to mention the blazing CI running costs.
We should strive to be as user-centric as we possibly can.
User’s visibility: is the user able to see what we intended to (not) show them on their screen? We won’t have to check visibility for every single line of text out there, just selective ones for each section.
User’s interactions: is the user able to interact with our rendered component in an expected manner? We can use the testing library to mimic user’s interactions, ranging from filling an input, clicking a button or dragging the form, depending on the defined use cases.
Subscription changes: what happens when there are changes to the redux store object or the media query that the component’s subscribed to? This should normally be covered in the user’s interactions part but there might be cases where we need to pay more attention to, especially when the component receive different props and needs to be re-rendered.
Let’s say we implement a simple popup modal for confirmation on deleting an item, we should aim to test what happens when:
Hope this helped, and have fun writing tests!