Automated testing in React
It is comprehensible that automated tests on front end might be an obscure subject for many developers, in view of the fact that before working in this new generation of Javascript, there weren’t many ways of testing the visual and interactive part of our applications. Nowadays, the Javascript community evolves fast, along with frameworks, libraries and resources to help us write tests and maintain quality in our projects.
Considering the testing pyramid, we’ll be focusing on unit tests in this article, since they are cheaper and faster to be done, and they guarantee a solid base for the application.
It’s important to remember that there is no unique and universal way of writing tests, in either react or any other technology. We should always analyze the context we are in and use patterns that fit our reality.
For the examples, we’ll be using React app, created using create-react-app.
Libraries used
JEST
Default testing library of create-react-app. It allows us to test snapshots, which are according to the official docs:
Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly.
A typical snapshot test case for a mobile app renders a UI component, takes a screenshot, then compares it to a reference image stored alongside the test. The test will fail if the two images do not match: either the change is unexpected, or the screenshot needs to be updated to the new version of the UI component.
That is, snapshots are like screenshots of the interface, and they make sure the component’s visualization won’t change unexpectedly.
Enzyme
Created by Airbnb, it allows the developer to simplify component rendering on the tests.
Enzyme is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components’ output.
Creating an example project
Let’s get started creating a project using create-react-app. The project is available on GitHub (https://github.com/thiagoferreiraw/react-testnig)
$ npm install -g create-react-app
$ create-react-app react-testing
$ cd react-testing
$ npm install -S prop-types
To check if the project was created successfully, run the test command:
$ npm test
The output should read as bellow, indicating the default test passed:
Installing dependencies and setting up the environment
The command bellow installs enzyme dependencies. Jest is already installed by default on create-react-app.
$ npm i --save-dev enzyme enzyme-adapter-react-16 enzyme-to-json
To setup Enzyme, create a file named react-testing/src/setupTest.js with the following contents:
// react-testing/src/setupTests.js
import { configure } from 'enzyme';import Adapter from 'enzyme-adapter-react-16';configure({ adapter: new Adapter() });
Creating a component
Our goal is quite simple: A component that receives a isLoggedIn and username props, and then renders the tasks for the logged user OR a login page for the unauthenticated user.
Writing the tests
Before writing the tests, we need to understand what is worth being tested in the component. In our case, we’ll evaluate the outputs for the inputs passed via props:
- Login page rendering;
- Authenticated user rendering, with tasks.
- Authenticated user rendering, without tasks.
Option 1: Manual asserts with Enzyme
In this approach, we’ll be mounting the component using Enzyme and asserting the output manually:
If any test fails, this will be our output:
Option 2: Using snapshots
Manual assertions with Enzyme is very useful, but we have a simpler way of making assertions in the result without having to write all the expected conditions we want to check:
We replaced the manual assertions and added only expect(toJson(app)).toMatchSnapshot(). It’ll create a file under __snapshots__ automatically, and this file contains all the rendering structure for the component. If we change anything in the component and don’t update the snapshot, the test will break as follows:
Pretty convenient, isn’t? To update the snapshot, just type “u” and Jest will save the new rendering and consider it as correct.
Coverage reports
To check out our test coverage reports, run the command:
$ npm test -- --coverage
We have an option of running the report on a browser, for a clearer visualization, and also being able to expand the components for more details. The file is created at:
/projeto/coverage/lcov-report/index.html
# Can be opened on any browser.
Conclusion
On Test Driven Development on the frontend, we have many libraries to test our components. Each project may have different testing strategies, depending on different factors, but it’s a necessary practice nowadays.
Tests will assure we can evolve our software with quality, guaranteeing more reliability to the users.
Any question? We are always open to discussion! Feel free to answer this story ❤
References:
Cover Photo by Max Nelson on Unsplash