We can do testing in React.js with the JavaScript testing framework Jest. It’s simple and can be utilized for broader categories. Jest accesses the DOM with the help of jsdom, which is an approximation of how browsers work; for React components this works well. Jest provides us with helpful features such as mock modules and timers, and boasts a fast iteration speed.
We can make use of Jest on the Create React App or we can use npm or yarn to install it.
This method provides an easy way to start with testing. When using this command for step-up of your project and when using Jest with it, you only need to add react-test-renderer to get rendering snapshots.
Create React Appnpx create-react-app app-name
Add react-test-renderer using yarnyarn add --dev react-test-renderer
Or using npmnpm install --dev react-test-render
If you don’t want to use Create React App then you can make use of the babel-jest package.
yarn add --dev jest babel-jest @babel/preset-env @babel/preset-react react-test-renderer
Next we can add scripts and Jest configuration in the package.json. After all this your package.json will look something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
"dependencies": { "react": "<current-version>", "react-dom": "<current-version>" }, "devDependencies": { "@babel/preset-env": "<current-version>", "@babel/preset-react": "<current-version>", "babel-jest": "<current-version>", "jest": "<current-version>", "react-test-renderer": "<current-version>" }, "scripts": { "test": "jest" }
Of note here is that we can use and build our transformer if we want more advanced functionality. In this case, we can use some @babel/core instead of using babel-jest.
To test whether our UI is rendering the right component we can use snapshot testing. In this, we use a reference snapshot file stored with the test, which is compared with a snapshot of the rendered UI component. When both of them match then the test passes. If they don’t match then the test fails. Also, we can use a renderer to quickly generate a serializable value for our react tree. When the snapshot test runs for the first time then it creates a snapshot file.
1 2 3 4 5 6 7 8 9 10 11
import React from 'react'; import renderer from 'react-test-renderer'; import Link from '../Link.react'; it('test the renders', () => { const tree = renderer .create(<Link page="http://www.topcoder.com">Topcoder</Link>) .toJSON(); expect(tree) .toMatchSnapshot(); });
If we want to update our snapshot then we can use the following command:
jest --updateSnapshot
We can also use the -u flag to regenerate snapshots. Make sure to fix all bugs before regenerating the snapshots. The above command will regenerate the snapshot for all failing snapshots, so if we don’t fix bugs it will record the snapshot for that bug, resulting in buggy behavior. We can also pass an additional flag –testNamePattern to make sure that only those tests for which this pattern matches will get regenerated.
We can use the interactive snapshot mode to update the failed snapshots. This interactive snapshot provides many features, some of which are as follows:
Some testing libraries can help us manipulate our rendered components like React Testing Library, Enzyme, and React’s TestUtils.
Let’s use Enzyme as an example. We can use Jest and Enzyme together to test React apps since they both complement each other. For using Enzyme we can use the command:
yarn add --dev enzyme
Also, for React versions below 15.5.0, we need to install react-addons-test-utils.
Checkbox component to test in LabelledCheckbox.js:-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React, {
useState
} from 'react';
/*implementing checkbox with label*/
const LabelledCheckbox = ({
labelOn,
labelOff
}) => {
const [isChecked, setIsChecked] = useState(false);
/* initially isChecked will be false */
const onChange = () => {
/*function to change state of checkbox */
setIsChecked(!isChecked);
};
return ( //render it
<label>
<input type="checkbox" checked={isChecked} onChange={onChange} />
{isChecked ? labelOn : labelOff}
</label>
);
};
export default LabelledCheckbox;
In this we have implemented a checkbox which has the property to swap between two different labels. Now let’s test this using Enzyme (using shallow renderer in Enzyme):
_tests_/LabelledCheckbox-test.js file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import React from 'react'; import { shallow } from 'enzyme'; //enzyme shallow renderer import LabelledCheckbox from '../LabelledCheckbox'; /*component to test*/ //testing using enzyme shallow renderer test('LabelledCheckbox changes the text after click', () => { // For Rendering a checkbox with a label const checkbox = shallow(<LabelledCheckbox labelOn="On" labelOff="Off" />); //our expected outcomes expect(checkbox.text()) .toEqual('Off'); checkbox.find('input') .simulate('change'); expect(checkbox.text()) .toEqual('On'); });
Now let’s use the React Testing Library to test the component. React Testing Library provides us a way to test React components since it is built by adding APIs with DOM Testing Library. If you are using the Create React App command for your project then you don’t need to install anything to use the library. Otherwise, you need to install it from the below npm command:
npm install --save-dev @testing-library/react
Below is an example to test a component using React Testing Library.
_tests_/LabelledCheckbox-test.js file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
import React from 'react'; import { cleanup, fireEvent, render } from '@testing-library/react'; /* react testing library */ import LabelledCheckbox from '../LabelledCheckbox'; /* component to be tested */ afterEach(cleanup); /* for performing cleanup after test is completed */ it('LabelledCheckbox changes the text after click', () => { const { queryByLabelText, getByLabelText } = render( <LabelledCheckbox labelOn="On" labelOff="Off" />, ); //our expected outcomes expect(queryByLabelText(/off/i)) .toBeTruthy(); fireEvent.click(getByLabelText(/off/i)); expect(queryByLabelText(/on/i)) .toBeTruthy(); });
In React, component testing is very important. React provides us with many testing libraries and using Jest with them makes it simple to test. Using Enzyme with Jest can make it even easier. Also, there are different ways to test in Jest, one of which is Snapshot testing, which is easy to implement.