GitHub Actions: Setting up Test Coverage for a JS/TS/Node project
Tags: github, git, devops, opensource
Published: 2020-08-13 12:20:32

This is a follow-up article to set up CI using GitHub Actions. Make sure you check out the [previous article](https://michaelzanggl.com/articles/github-actions-ci-setup/) first.

Today let's focus on test coverage. At the end of this article your project's README will have one additional badge just like this one:


![Coverage Status](https://coveralls.io/repos/github/MZanggl/flooent/badge.svg?branch=2.0)

Additionally, coverage results will be added to PRs as a comment.

![showing coverage status in a PR](https://camo.githubusercontent.com/8303ee41ef9f75fa0c756bf3b6e8cd9391b58ed8/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6173736574732e636f766572616c6c732e696f2f436f766572616c6c73253230476974687562253230416374696f6e25323044656d6f2532302d2532307472696d6d65642532302d253230342e38783732302e676966)

## Prerequisites

To save the coverage results and for the PR wizardry above we use a tool called [Coveralls](http://coveralls.io/). Make sure to connect your GitHub account with it. Under "Add repo", add the repository you want to include.

**Notice that with the free tier, the repository has to be public.**

## Adding the test coverage script

If you use jest to run your tests, you can supposedly run `jest --coverage` to create a coverage report. In my case though, I am using [japa](https://github.com/thetutlage/japa) which doesn't come with its own test coverage system.

So instead, let's make use of [nyc](https://github.com/istanbuljs/nyc), the istanbul CLI.

We simply add an additional script to our package.json:

#### Before

```javascript
"scripts": {
    "test": "node japaFile.js"
}
```

#### After

```javascript
"scripts": {
    "test": "node japaFile.js",
    "coverage": "nyc --reporter=lcov npm test"
}
```

`--reporter=lcov` means it will create a `./coverage/lcov.info` to save the coverage results. *We only need to the results on the CI pipeline, if you run this command locally, you can safely gitignore or delete the results again.*

To see the coverage results directly in the terminal, temporarily remove `--reporter=lcov` and run `npm run coverage`.

## Adding test coverage to our CI pipeline

Now all that's left is to add a little bit to the `ci.yml` file we created in the previous article.

First, let's replace

```yml
run: npm test
```

with

```yml
run: npm run coverage
```

This will now create the coverage reports when we run the pipeline. Finally, let's send the reports to Coveralls. By convention, it will look for `./coverage/lcov.info`, which was created by the `npm run coverage` script.

Add this additional step to the yml file:

```yml
    # Send coverage report to Coveralls
    - name: Coveralls
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
```

We make use of Coveralls' GitHub Action which can be found [here](https://github.com/marketplace/actions/coveralls-github-action).

Note that GITHUB_TOKEN is automatically passed and does not have to be configured by you in any way. Since our GitHub account is linked with Coveralls, there is also no additional setup necessary to authenticate your Coveralls account.

Altogether, our `ci.yml` file looks like this:

```yml
# This workflow will do a clean install of node dependencies, build the source code and run tests
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: CI Pipeline

# trigger build when pushing, or when creating a pull request
on: [push, pull_request]

jobs:
  build:

    # run build on latest ubuntu
    runs-on: ubuntu-latest

    steps:
    # this will check out the current branch (https://github.com/actions/checkout#Push-a-commit-using-the-built-in-token)
    - uses: actions/checkout@v2
    # installing Node
    - name: Use Node.js 12.x
      uses: actions/setup-node@v1
      with:
        # this will use the latest Node 12 version
        node-version: 12.x
    # install dependencies using clean install to avoid package lock updates
    - run: npm ci
    # build the project if necessary
    - run: npm run build --if-present
    # finally run the tests
    - run: npm run coverage

    # Save coverage report in Coveralls
    - name: Coveralls
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
```

Now push the changes, watch the build, check the results in Coveralls, grab your badge add stick it to your README.

---

Aaand that's all there is to it. Now all that's left is to set up the CD workflow so we can automatically publish to NPM. Check out my guide for it [here](https://michaelzanggl.com/articles/github-actions-cd-setup).