GitHub Actions: Setting up Test Coverage for a JS/TS/Node project

Published 8/13/2020

This article is part of a series:


This is a follow-up article to set up CI using GitHub Actions. Make sure you check out the previous article 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

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

showing coverage status in a PR

Prerequisites

To save the coverage results and for the PR wizardry above we use a tool called Coveralls. 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 which doesn't come with its own test coverage system.

So instead, let's make use of nyc, the istanbul CLI.

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

Before

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

After

"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 workflow

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

run: npm test

with

run: npm run coverage

This will now create the coverage reports when we run the workflow. 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:

    # 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.

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:

# 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 and stick it to your README.

Check out my e-book!

Learn to simplify day-to-day code and the balance between over- and under-engineering.

Aaand that's all there is to it. Now all that's left is to set up the CD workflow. Until then ;)