Starting up with NodeJs from the beginning with TDD in mind

I started playing with NodeJs. It’s a separate topic why and how, but my overall approach was that from the beginning I wanted to have that TDD habit included in the checkout/code/run/test/build/commit daily workflow.

For me, being complete newbie in the sphere of NodeJs it has taken about hour to set things up correctly, which at the end I can say is very intuitive, yet with lack of good documentation a few Google searches were needed, mostly followed by StackOverflow lecture.

I decided to describe the whole process in this post blog as with my searches I didn’t find any single place where it’s very well explained with complete newbie in mind of the authors and contributors.

First of all you need NodeJs, and if you don’t know where and how to find it, then probably this post isn’t for you. Node comes with interesting package manager called NPM and which comes with handly command line tool with the same name but in lower case.

Using it you can add additional components to your NodeJs project and those components will be nicely encapsulated in ./node_modules/* folder structure.

What you can start with is to install a few critical modules that are really helpful in test driven development where you need handy tools for manual unit testing and growing your unit testing base in natural – code first – way. Additional tools I recommend are helpful for code coverage that is suplemental to all TDD tactics known to me.

So, lets begin with:

npm install mocha
#which installs Mocha – great and very usable unit testing environment

npm install should
#which you will belove for great assertion syntax that complements core Mocha and NodeJs assertion routines

And last component you need is node-jscoverage which I initially added also through.

npm install jscoverage

but for some reason package pushed to NPM is kinda broken and for this short time I quickly decided to clone node-jscoverage directly from github (https://github.com/visionmedia/node-jscoverage) and manually copy all sources in my ./node_modules/jscoverage folder.

JsCoverage has lot of C/C++ code which you need to compile, the easiest way (and one which is not broken, comparing to NPM) is to run the sequence of commands:

./configure
make

and in root directory you should get some executables, including jscoverage and jscoverage-server.
Now lets add some code of our own targeting NodeJs in a structure:

./node_modules/ #you leave that alone, just utilize in your scripts

./src #folder with your source code
./src/server.js #let’s call it main routine for your application
./src/someClasses.js #let’s call it additional includes for your project

./tests/ #folder with your unit tests
./tests/someClasses.test.js #unit test package targeting ../src/someClasses.js

Obviously and assuming correct code inside all files to run your NodeJs server in dev environment you only need to type:

node src/server.js

or more often if in root folder of your project you create some index.js with all included requirements, then code will look like:

node index.js

We’re good. But how about testing? Mocha comes with executable located in ./node_modules/.bin/mocha and we will use it

To run tests you need to make following call:

./node_modules/.bin/mocha tests/*.test.js

That’s it. In response you will get result like below:

․․․

3 tests complete (3 ms)

Or longer and more detailed, if your tests fail.

If you want to check coverage of your tests then you have to rig jscoverage with mocha. It’s relatively simple.
Command jscoverage [SRC] [DST] copies your code from one folder to another and in destination folder it creates a copy with additional markets needed to run coverage report smoothly. It cannot replace existing folder so each time you call it make sure that you deleted (or scripted the deletion) of older instance.

In my case it’s:

./node_modules/node-jscoverage/jscoverage ./src ./src-cov

Then having that done, you have to re-run your mocha with additional parameter for code coverage.
I encourage experiment with two outputs: html and json with below variations:

./node_modules/mocha/bin/mocha -R html-cov tests/*.test.js > report.html
./node_modules/mocha/bin/mocha -R json-cov tests/*.test.js > report.json

Last very important thing. If you normally required include files from your original ‘src’ folder then your code coverage will show nothing. You need to point your includes into ‘src-cov’ folder, not to slow down regular tests with additional code that jscoverage produces, I recommend to make a script that prior to code coverage testing will set environment variable and that variable will be included in your unit tests, like below example:

var myClasses = process.env.COV_REPORT ?
require(‘../src-cov/someClasses.js’) :
require(‘../src/someClasses.js’);

In my case, additionally I wanted to stay in the shell with all runs so I crafted little Javascript code executed by Node in parallel to show me the summary from JSON report and I created complete script for code coverage that looks like below files:

File: ./runCoverage

#!/bin/csh
#setting env for mocha

setenv COV_REPORT 1

if ( -d “src-cov” ) then
rm -dfR src-cov
endif

./node_modules/node-jscoverage/jscoverage src src-cov
./node_modules/mocha/bin/mocha -R html-cov tests/*.test.js > report.html
./node_modules/mocha/bin/mocha -R json-cov tests/*.test.js > report.json

unsetenv COV_REPORT

node ./coverageReportSummary.js

File: coverageReportSummary.js 

var coverageReport = require(‘./report.json’);

console.log(‘\nCode coverage report:’);
console.log(‘* SLOC Total: \t\t’ + coverageReport.sloc);
console.log(‘* SLOC hit with tests: \t’ + coverageReport.hits);
console.log(‘* SLOC missing tests: \t’ + coverageReport.misses);
console.log(‘* Code Coverage (%): \t’ + coverageReport.coverage.toFixed(2));
console.log(‘More detailed report available in *report.html*\n’);

And the final output from runCoverage script looks like that:

Code coverage report:
* SLOC Total: 54
* SLOC hit with tests: 32
* SLOC missing tests: 22
* Code Coverage (%): 59.26
More detailed report available in *report.html*

Just some tweaking or massaging as some of my friends would say, but I like it. Happy coding!

 


Leave a Reply