In this tutorial I would like to show you how easy it is to create code coverage for your React application. We will use the popular create-react-app to set up our application. Everything we need is already in place and keeping an eye on the overall code coverage is a no-brainer.
Let us start by creating a new application called cra
.
$ npx create-react-app cra
$ cd cra
$ npm start
npm test
starts watching your files and running your tests continuously.
No tests found related to files changed since last commit.
Press `a` to run all tests, or run Jest with `--watchAll`.
Watch Usage
› Press a to run all tests.
› Press f to run only failed tests.
› Press q to quit watch mode.
› Press p to filter by a filename regex pattern.
› Press t to filter by a test name regex pattern.
› Press Enter to trigger a test run.
However it does not emit code coverage. Stop the watch mode by pressing CTRL+C and start a single run that also emits the coverage at the end as described in the docs.
$ npm test -- --coverage --watchAll=false
PASS src/App.test.js
✓ renders without crashing (15ms)
------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
------------------|----------|----------|----------|----------|-------------------|
All files | 2.44 | 0 | 6.25 | 2.44 | |
App.js | 100 | 100 | 100 | 100 | |
index.js | 0 | 100 | 100 | 0 | 7,12 |
serviceWorker.js | 0 | 0 | 0 | 0 |... 23,130,131,132 |
------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.317s
Ran all test suites.
The default coverage for all files of 2.44%
is so low because serviceWorker.js
is quite large compared to the other files and does not have any unit tests. Notice the double --
after npm test
which tells the script to pass the following arguments further down to react-scripts
. Use --watchAll=false
to start a single run with code coverage. The default reporter emits more information than necessary and also separates the values, e.g. 2.44
, from the units, e.g. %
. As the documentation explains we are able to override the coverageReporters
field inside our package.json
.
{
...,
"jest": {
"coverageReporters": ["text-summary"]
}
}
Afterwards we run our test command again and get a more useful result. This time it contains less noise and we have the final numbers combined with their units.
$ npm test -- --coverage --watchAll=false
PASS src/App.test.js
✓ renders without crashing (17ms)
=============================== Coverage summary ===============================
Statements : 2.44% ( 1/41 )Branches : 0% ( 0/32 )
Functions : 6.25% ( 1/16 )
Lines : 2.44% ( 1/41 )
================================================================================
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.333s
Ran all test suites.
The most interesting line for us is where it says Statements: 2.44% ( 1/41 )
. This is the number we are interested in and that we would like to monitor. In order to get only the value we use a combination of grep
and awk
.
$ npm test -- --coverage --watchAll=false | grep Statements | awk '{print $3}'
2.44%
Now we are done. We can write a simple script and tell our Continuous Integration to post this value to seriesci and track its progress.
- run:
name: post code coverage to seriesci
command: |
npm test -- --coverage | grep Statements | awk '{print $3}' | xargs -I {} curl \
--header "Authorization: Token ${TOKEN}" \
--data-urlencode value="{}" \
--data sha="$(git rev-parse HEAD)" \
https://seriesci.com/api/repos/seriesci/cra/coverage/combined
See the result live at our demo application github.com/seriesci/cra available at GitHub and at seriesci seriesci.com/seriesci/cra.
We hope we could show you how easy it is to create code coverage during Continuous Integration and to keep an eye on it over time.