TODO: find examples
Mount your app (page) root component and test happy path and main error cases with Enzyme.
This way you can validate that the app is actually working and doing what you want.
Test all Redux actions by creating a store and dispatching actions on this store.
This way you’ll test the whole Redux chain: action creators, reducers and selectors.
The state update logic in reducers may be complex and having good coverage is essential. Though unit-testing reducers separately won’t bring much value over duck-testing the whole Redux chain, but will slow down changes.
Test static functions that contain tricky logic.
This way you can be sure that all calculations and logic are correct, and edge cases are properly handled.
This will also make code more independent and isolated. You won’t be tempted to keep such functions inside React components, because it’ll make testing harder.
We want to be sure that any changes, especially done by other teams, won’t break our code. We also want to be able to refactor our code safely.
So we should spend most of our testing efforts on tests that will give us the most confidence, witch the least maintenance time.
Too many low-level (unit) tests make code changes harder and slower without giving you much confidence. They are tightly coupled to the implementation: any code changes will require tests to be updated, just moving code around will break many tests. Unit tests can’t guarantee that the app is actually working, even with high code coverage.
High-level (integration) tests may be harder to write, but they don’t depend on implementation details and won’t break that often during refactoring. They will give us confidence but won’t slow slow down code changes.