Node.js project quick-start

February 28, 2015

After setting up a Node.js development environment, let's create a project. This project will include everything we need for development, testing, code coverage, and continuous integration.

Project skeleton

First, we'll initialize a brand new project with npm.

$ mkdir node-quickstart
$ cd node-quickstart
$ npm init
This utility will walk you through creating a package.json file.

Press ^C at any time to quit.
name: (node-quickstart)
version: (1.0.0) 0.1.0
description: A quick-start guide for Node.js projects.
entry point: (index.js) lib/node-quickstart.js
test command: mocha
git repository:
keywords: node, mocha, test, continuous integration, coverage, travi
author: James Earl Douglas
license: (ISC) MIT
About to write to /home/james/code/node-quickstart/package.json:

...

Is this ok? (yes)
$

Let's make some entry points for our code.

$ mkdir lib test
$ touch lib/node-quickstart.js
$ touch test/node-quickstart.js

Development dependencies

We'll use mocha for testing, istanbul for code coverage, mocha-lcov-reporter to generate coverage reports and coveralls to report them.

$ npm install --save-dev --save-exact mocha istanbul mocha-lcov-reporter coveralls

We're using --save-dev to designate these as development dependencies, to be required only internally by this project. We're using --save-exact to prevent version skew of these dependencies, so they don't change out from under us and break unexpectedly.

Now our package.json includes a devDependencies section:

"devDependencies": {
  "coveralls": "2.11.2",
  "istanbul": "0.3.6",
  "mocha": "2.1.0",
  "mocha-lcov-reporter": "0.0.2"
}

We'll also need to tell npm how to run and report code coverage reported by adding coverage and coveralls fields to scripts in package.json:

"scripts": {
  "test": "mocha",
  "coverage": "istanbul cover _mocha -- -R spec",
  "coveralls": "cat ./coverage/lcov.info | coveralls"
},

Failing test

Let's write a test for a function, hello(), that doesn't yet exist.

test/node-quickstart.js:

'use strict';

/* global describe, it, before, beforeEach, after, afterEach */

var assert   = require('assert');
var nodeqs   = require('../lib/node-quickstart');

describe('hello', function(){
  it('should greet the world', function(){
    assert.equal('Hello, world!', nodeqs.hello());
  });
});

When we run this test, it fails.

$ npm test

> node-quickstart@0.1.0 test /home/james/code/node-quickstart
> mocha

  hello
    1) should greet the world

  0 passing (7ms)
  1 failing

  1) hello should greet the world:
     TypeError: Object #<Object> has no method 'hello'
      at Context.<anonymous> (/home/james/code/node-quickstart/test/node-quickstart.js:10:42)

npm ERR! Test failed.  See above for more details.
npm ERR! not ok code 0

We expect this test to fail because we haven't implemented hello() yet.

Passing test

Let's write hello() and get that test passing.

lib/node-quickstart.js:

'use strict';

function hello() {
  return "Hello, world!";
}

module.exports.hello = hello;

The test should now pass:

$ npm test

> node-quickstart@0.1.0 test /home/james/code/node-quickstart
> mocha

  hello
    ✓ should greet the world

  1 passing (7ms)

Let's check the code coverage:

$ npm run-script coverage

> node-quickstart@0.1.0 coverage /home/james/code/node-quickstart
> istanbul cover _mocha -- -R spec

  hello
    ✓ should greet the world

  1 passing (5ms)

=============================== Coverage summary ===============================
Statements   : 100% ( 3/3 )
Branches     : 100% ( 0/0 )
Functions    : 100% ( 1/1 )
Lines        : 100% ( 3/3 )
================================================================================

Cool, full coverage!

Continuous integration

Our tests are passing and our coverage looks good. Before we push this code to origin, let's set up Travis CI and Coveralls to continuously test and report on the state of our code.

Browse to travis-ci.org/profile/, find the project, and enable it.

Travis CI project switch
Travis CI project switch

We might need to hit the sync now button first:

Travis CI repositories synchronization
Travis CI repositories synchronization

We'll need a brief configuration file to tell Travis CI what to do when commits are pushed:

.travis.yml:

language: node_js
node_js:
- '0.10'
after_script:
- npm run-script coverage
- npm run-script coveralls

Now browse to coveralls.io/repos/new, find the project, and enable it.

Coveralls project switch
Coveralls project switch

We might need to hit the refresh private repos button first.

Coveralls repositories synchronization
Coveralls repositories synchronization

Status badges

Travis CI and Coveralls provide spiffy status badges that can be included in documentation (e.g. README.md) to report the build and coverage status:

Ship it

Let's push our code and watch the continuous integration continuously integrate!

$ git push origin master

After pushing, Travis CI picks up the changes, triggers a new build, and sends the coverage report to Coveralls.

We can see the build results at travis-ci.org/earldouglas/node-quickstart:

Travis CI build results
Travis CI build results

We can see the coverage report at coveralls.io/r/earldouglas/node-quickstart:

Coveralls coverage report
Coveralls coverage report