DEV Community

Daniel Chima
Daniel Chima

Posted on

Integrating CircleCI with Coveralls for Your Next Node Project.

Prerequisite

  • First, we need a set up node project. I'm currently running a graphql project of my own. it's a boilerplate project with no controller code. All we need is a project with a running server.
  • We need to run tests. code coverage works by calculating the percentage of your source code covered in tests. you can read more about code coverage here.

For this project we will run an index test. A simple check to see that one thing equals another.

Continuous Integration with CircleCI

Let's start with integrating CI into the project, by signing up to CircleCI. We can do this with out github account, which will authorise the CircleCI app on our account. Next, we add the repository we are trying to integrate with CircleCI. Once we ad the repository, CircleCI will tell us to either download a config.yml setup file, or add it automatically to our repository (in a .circleci folder in root). For this walk through, just click on start building.

On the initial build, our CircleCI integration will fail. This is because we are yet to add our config.yml file, and there are no tests in our code.

Screenshot 2020-05-11 at 08 57 01

The next step is to allow for orbs in our CircleCI organisation directory. CircleCI orbs are 'shareable packages of configuration elements, including jobs, commands, and executors'. This allows you to use 3rd party apps to enhance your CI workflow. To use the coveralls orb, we need to opt-in to 3rd party orbs on our organisation’s security settings page, since coveralls orb is not a CircleCI partner. you can read more about this here.

orb-setup

Connecting with Coveralls

Now that we've got our CircleCI setup sorted, it's time to sort out our code coverage with coveralls. We'll head on over to coveralls, and signup with our github account. we will be redirected by github to authorise the coveralls web app for our repositories. click authorise.

Here, we'll add the repository we want to track the coverage of. Once the repository is added, there will be no builds recorded. This is because we've not yet done any heavy lifting. Navigate into the repository page in coveralls and copy the repo token. Save it somewhere safe. This token will be integral to further integrations. That's all we need to do to setup the repository in coveralls.

Repository Setup

Setting up the Job

  • in our local code (or directly in github), we'll add the config.yml file below in a .circleci folder in our root directory.
version: 2.1
orbs:
  coveralls: coveralls/coveralls@1.0.4
jobs:
  build:
    docker:
      - image: circleci/node:10.16.0
    working_directory: ~/project-api
    environment:
      NODE_ENV: test
      DATABASE_URL: process.env.DATABASE_URL_TEST
    steps:
      - checkout
      - run: npm install
      # - run: npm test
      - restore_cache:
          key: dependency-cache-{{ checksum "package.json" }}
      - run:
          name: install-npm-wee
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package.json" }}
          paths:
            - ./node_modules
      - run: # run tests
          name: test
          command: npm run test
      - run: # run code coverage report
          name: code-coverage
          command: npm run coverage
      - coveralls/upload
      - store_artifacts: # special step to save test results as as artifact
          # Upload test summary for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
          path: test-results
          prefix: tests
      - store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
          path: coverage
          prefix: coverage
      - store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
          path: test-results
      - run: # test what branch we're on.
          name: "What branch am I on?"
          command: echo ${CIRCLE_BRANCH}
notify:
  webhooks:
    - url: https://coveralls.io/webhook?repo_token=${process.env.COVERALLS_REPO_TOKEN}

Let's break down this code bit by bit so we know what's happening. in every line. it will instruct the entire workflow of our integration in CircleCI

version: 2.1
orbs:
  coveralls: coveralls/coveralls@1.0.4

First, we start with the CircleCI infrastructure version we want to use. Here it's the 2.x infrastructure. The second part is setting up the CircleCI orbs. We need to use the coveralls orb, as we want to share coverage data between CircleCI and coveralls. you can read more about CircleCI coveralls orb here.

jobs:
  build:
    docker:
      - image: circleci/node:10.16.0
    working_directory: ~/project-api

I am using docker for my project, so I've add an image of the node environment needed, as well as the route to the working directory.

    environment:
      NODE_ENV: test
      DATABASE_URL: process.env.DATABASE_URL_TEST

Here, we specify that the current environment we're working on is the test environment, so CircleCI is able to run our test code. We also specify the database the tests are to be run against (This variable values should be placed in the CircleCI environment variables setting.

    steps:
      - checkout
      - run: npm install
      # - run: npm test
      - restore_cache:
          key: dependency-cache-{{ checksum "package.json" }}
      - run:
          name: install-npm-wee
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package.json" }}
          paths:
            - ./node_modules

This section tells the CircleCI job to either restore the cached package.json dependencies/dev-dependencies it currently has for this particular project (from previous builds), or install the modules again, and save the node_module into its current cache.

      - run: # run tests
          name: test
          command: npm run test
      - run: # run code coverage report
          name: code-coverage
          command: npm run coverage
      - coveralls/upload
      - store_artifacts: # special step to save test results as as artifact
          # Upload test summary for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
          path: test-results
          prefix: tests
      - store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
          path: coverage
          prefix: coverage
      - store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
          path: test-results

This is the meat of the CircleCI process. In this section, we tell the job to run the tests we've written for our project. The test files are normally placed in a /test folder in the project /src folder.When all the test are completed (and successful), we tell the job to run our code coverage, to get the percentage of source code covered by our tests. After performing the code coverage, the job stores our coverage in CircleCI artifacts. We also store the test results themselves, making them visible in the CircleCI web application terminal (normally under the test summary section).

      - run: # test what branch we're on.
          name: "What branch am I on?"
          command: echo ${CIRCLE_BRANCH}

This allows us to view, through the CircleCI application terminal, the exact repository branch being tested during the job.

notify:
  webhooks:
    - url: https://coveralls.io/webhook?repo_token=${process.env.COVERALLS_REPO_TOKEN}

This final section of the code is where we add the coverall web-hook to the CircleCI build. This web-hook is called at the end of the build. Coveralls is notified upon success of each build, and uses the test coverage data we ran and stored earlier to show the percentage coverage.

To be certain of which repository this coverage is for, in the coveralls web app, we need to pass the repository token to the url (remember the token we saved from coveralls earlier?). Add the COVERALLS_REPO_TOKENas an environment variable in the CircleCI project settings, with the repo token as its value.

Mocking the Test

Now you know what the CircleCI config file is doing, let's add a mock test to our database. Create a /test folder in your /src folder, and add an index.js file. This is where we'll place our simple test. Copy and paste the code below.

import chai from 'chai';

const { expect } = chai;

describe('Initial test', () => {
  it('should be equal to generic thing', () => {
    expect('this thing').to.equal('this thing');
  });
});

As you can see, we've written a mock test that simply checks if the first string is equal to the second string. now we need to install a few useful npm packages, and edit our scripts. run this in your terminal

npm i --save-dev nyc mocha-lcov-reporter mocha chai coveralls @babel/register

After installation, add the test scripts below to your package.json

{
  "scripts": {
    "test": "cross-env NODE_ENV=test nyc --reporter=lcov --reporter=text --reporter=html mocha src/test/*.js --timeout 10000 -c --require @babel/register --exit",
  },
  "coverage": "nyc report --reporter=text-lcov | coveralls",
}

These test script allows the application to run the specified files in the /test folder, as well as save the test coverage report. This coverage report can also be viewed from the CircleCI web application, as we've specified in the job config script. The coverage command will be ran in CircleCI to generate the coverage files needed by coveralls. We can now run our local test (in the terminal), to see that it works.

$ npm run test

Screenshot 2020-05-11 at 08 44 39

Let's push our repository changes to github. If we raise a pull request on our branch with our commit, we should see the CircleCI pull request check mark, showing a successful build. if everything goes right, we should also see the coveralls check mark on the pull request.

Screenshot 2020-05-10 at 18 10 10

Back in our CircleCI web environment, we can see our build status as successful, and we should be ready to go. Over at our coveralls web app, we can also confirm that the build coverage has been recorded.

That's it. we've successfully integrated CircleCI alongside coveralls in our node project.

Screenshot 2020-05-11 at 08 57 58

Screenshot 2020-05-11 at 08 58 20

Badges.
Badges help external developers know the status of our repository. letting them know if our development branch passes its tests, as well as the current code coverage on that branch. Badges are placed in the README.md file of oour repository.

Screenshot 2020-05-11 at 08 59 27

To get a CircleCI badge, we need to navigate to our project settings in CircleCI. Under API permissions, click on add api token, with its scope as status. We'll can label it anything we like, or keep the label empty. Save that token and add it to the badge path below.

[![CircleCI](https://circleci.com/gh/YOUR-GITHUB>/<YOUR-REPO>/tree/<YOUR-HEAD-BRANCH>.svg?style=svg&circle-token=<YOUR-TOKEN>)](https://circleci.com/gh/YOUR-GITHUB>/<YOUR-REPO>/tree/<YOUR-HEAD-BRANCH>)

For coveralls, there is no token required in the badge themselves. let;s navigate to our repository on coveralls, copy the badge for our head branch and add it to our README.md. The badges usually come in the format below.

[![Coverage Status](https://coveralls.io/repos/github/<YOUR-GITHUB>/<YOUR-REPO>/badge.svg?branch=<YOUR-HEAD-BRANCH>)](https://coveralls.io/github/<YOUR-GITHUB>/<YOUR-REPO>?branch=<YOUR-HEADBRANCH>)

Happy coding.

Top comments (4)

Collapse
 
anujpancholi profile image
Anuj Pancholi • Edited

Hi. I set up a circleci workflow for one of my repos to send the coverage info to coveralls via the coveralls circleci orb. I ran the coveralls/upload command once in verbose mode and after logging the contents of the coverage/lcov.info file, it's definitely sending something to coveralls with a 200 response, and the entire pipeline is succeeding, but nothing is reflecting on the coveralls dashboard, and the coverage badge still says "unknown".

I don't have a .coveralls.yml file in my project but from what I know it's optional and just stores the token required by coveralls, which I already have set in my env vars in circleci. Can't seem to figure out what's wrong. Please help.

circleci coveralls/upload verbose output

Collapse
 
anujpancholi profile image
Anuj Pancholi

Update:

It seems coveralls is just slow. I checked a day later without making any changes, the build was there but the badge wasn't updated. I merged the PR with the circleci config changes and a day after that the badge got updated.

updatedBadge

Collapse
 
gouravjat profile image
Gourav Singh Jat

Facing similar issue, please help.

Collapse
 
tylim88 profile image
Acid Coder

thank for the guide, I use jest and jest can generate coverage test, I dont need to install coverall as dependency

coverall are much easier to setup then codecov, codecov also report my coverage incorrectly