A fresh look at testing Node.js projects: Mocha, Should and Travis
By David WORMS
Feb 19, 2012
Never miss our publications about Open Source, big data and distributed systems, low frequency of one email every two months.
Today, I finally decided to spend some time around Travis. It’s been a few weeks since that little green image on top of many GitHub homepages has been buzzing me. Well, to be totally honest, this isn’t how I started my evening. First, after 2 years of good and faithfull service, I decided to drop Expresso and gave a chance to Mocha. Because Expresso enriches the assert
module with one or two functions which I became addicted to. I also had to find the same functionalities into another assertion library which lead me to testing Should. It is very pleasant to see those two working together, as in the Unix tradition: small, powerful and naturally integrated.
Written by the same author than Expresso, Mocha is meant to replace it. It’s been the case since quite a while but I’ve always been reluctant to jumping into BDD testing. BDD stands for Behavior Driven Development and is an alternative way to express your tests. For example, test names are expressed as a full sentence. Its goal is to encourage collaboration between developers, QA and non-technical or business participants in a software project. This is probably applicable in some workspaces but from a personal experience, it can’t expect our clients to participate in test coverage. Cucumber is probably the most popular BDD tool, it has its fans but I’ve been too lazy in the past to jump into BDD. Facing any sample, It feels like learning a new language to write tests. Probably it was a wrong impression and it might be much easier than I think.
Now let’s have a look at Mocha. The API is quite simple, mainly two functions which are describe
and it
. They both take a text as a first argument which combining together produce a sweet sentence during the run. An example:
describe 'My test', ->
it 'should run synchronously', () ->
# do sth
it 'should run asynchronously', (next) ->
# do sth
next()
Notice how Mocha discovers and lets yet decide whether you wish to run your tests synchronously or not, even mixing the two modes. Behind the hood, it’s making use of the not so popular length
property attached to a function. There are few additionnal methods that come handy to modify settings and to setup and cleanup your tests. For illustration purpose, here is an example inspired from the mecano test suite:
should = require 'should'
mecano = require 'mecano'
describe 'download', ->
@beforeEach (next) ->
mecano.mkdir scratch, next
@afterEach (next) ->
mecano.rm scratch, next
it 'should deal with ftp scheme', (next) ->
@timeout 10000
mecano.download
source: 'ftp://ftp.gnu.org/gnu/glibc/README.glibc'
destination: "#{scratch}/download_test"
, (err, downloaded) ->
should.not.exist err
downloaded.should.eql 1
next()
The functions beforeEach
and afterEach
allow code execution before and after each test. The function timeout
modifies the maximum execution time of a test (by default 2 seconds).
Here, let’s introduce the usage of Should.js. Its purpose like any assertion library is to detect incorrect returned variable. At first, the BDD style API may look complicated but I found it natural and I didn’t have to fight against it. Well, I said it all. This is essentially what I’m expecting from such a library, not opening my browser to figure out how to use the API. After 10mn of usage, Should.js has proved to be easy, delivered its promises and enhance code readability (to my opinion).
Finally, I decided to deal with this Travis status. Getting the image popping up into the mecano GitHub page was easy. Travis setup and GitHub integration for a newbie took less that 15 minutes. To make it green took a little longer. Mecano is making a few assumptions when running its test. It must be online, have GIT installed and be able to SSH itself. It turns out I was positively surprise on the first run, only 5 tests where not passing. Most of them were my fault and I fixed them. Another one was Should.js usage of JavaScript which was incompatible with the one used by Node.js in version “0.4”. That left me with only one issue, setting up the Travis user account in such a way it can SSH itself without a password asked. In the end, my “.travis.yml” configuration file looks like:
language: node_js
node_js:
- 0.6
- 0.7
before_script:
- "ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ''"
- "cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys"
During this presentation, I did not provide any instruction related to installation and configuration because each project is very well documented. Thanks to the author of those tools for their appreciable work.