Tests - acolorbright/handbook GitHub Wiki
Writing tests is not mandatory at ACB but encouraged where it makes sense. In general we encourage the use of unit tests to make sure your code does what it's supposed to as well as provide a living form of documentation for other developers. Always keep in mind, if a piece of code is providing too difficult to unit test or requires too much mocking it is probably too tightly coupled and might make sense to refactor.
Tooling
The following tooling is industry standard and proven to work well:
Javascript:
- Jest or Mocha.
- Enzyme for various helpful component rendering tools.
- Should, Tape or Jest for assertions.
Testing of React Components:
What makes sense to test? (the following is summarized from here)
It must render:
At the very least, make sure the component renders without error. This verifies there are no JSX syntax errors, that all variables are defined, etc. This could be as simple as verifying that the rendered output is not null.
Test the output:
One step above “it renders” is “it renders the correct thing.” Given a set of props, what output is expected? Does Person render its name and age, or does it render a name and “TODO: age coming in v2.1”?
Test the states:
Every conditional should be accounted for. If the classNames are conditional (enabled/disabled, success/warning/error, etc), make sure to test that the className-deciding logic is working right. Likewise for conditionally-rendered children: if a Logout button is only visible when the user is logged in, for instance, make sure to test for that.
Test the events:
If the component can be interacted with (an input or button with an onClick or onChange or onAnything), test that the events work as expected and call the specified functions with the correct arguments (including binding this, if it matters).
Test the edge cases:
Anything that operates on an array could have boundary cases — an empty array, an array with 1 element, a paginated list that should truncate at 25 items, and so on. Try out every edge case you can think of, and make sure they all work correctly.
Testing Redux:
In general the most value with the lowest effort here is to unit test Reducers and Actions, making sure that state changes happen as they should and you've accounted for all cases. Due to the nature of Redux's design it is fairly simple to test synchronous state changes, the Redux Devtools extension for chrome and firefox can help in providing the necessary boilerplate for writing tests.
The Redux docs provide an excellent starting point for instructions on writing unit tests.
General Tips:
- Unit testing of any kind of 'utility functions' is often a low hanging fruit since these are isolated and abstract some business logic that is probably worth verifying.
- For anything 'impure', time/date, external API calls, random numbers use mocks.
- A good rule of thumb is to identify any pieces of logic scattered around your code and abstract them into functions with explicit dependencies and unit test these in isolation.
- Write tests. Not too many. Mostly integration.