NodeJS is awesome. I've used it for many pet projects and have worked on commercial projects which have made good use of Node in sticky situations. When it comes to testing Node, we're spoiled. My favourite testing framework is Mocha[1] and my favourite testing library is should.js[2]. We'll be using that alongside Jenkins to build an automated test suite for our demo repository.
Mocha[1] is our testing framework. We use it to describe the tests we want to make.
Should.js[1] is our assertion library. We use Should to check something is as expected. We use should.js within the context of Mocha to decide whether the test has passed or failed.
We use Ant[1] to set up and prepare the environment for a test. We run Mocha inside of ant and return the result. The advantage of using Ant is that you can also run the same test you're running on Jenkins on your development machine.
Of course, we also need to run Jenkins[1]. As well as Jenkins, we'll also need a few plugins:
We're going to use Git to track the changes in our code, and to "tag" the latest passing build. That way, we know what builds we can use in production. We could even get Jenkins to push the code onto our web server later if we wanted to (if you want me to write about that just ask!).
Anything will do really; the faster the server the faster the tests will run. I will use a Debian-based distribution (such as Ubuntu[1] for the purposes of this article. I'd recommend you use a dedicated machine (not necessarily a dedicated hosted server!) to run your builds if you have the capacity, as testing could be rather processor intensive (less-so for testing node; more so for compiling statically typed languages), but it all depends on your situation and what your NodeJS code is doing.
The first thing it to install your distribution of choice (I'll be using Ubuntu) on your server if it isn't already. There are a million articles online explaining how to do that, so pick one and go for it. If it's the first time you've installed a linux distribution, you might be surprised at how simple it is! While it's installing, move on to the next step...
You'll need an SSH key for your Git Repository.
If you are using bitbucket, follow this tutorial
If you are using Github, follow this tutorial
One way to do this (there are a few ways) is to use `scp`. `scp` is simply `cp` over `ssh`. If your private key is called `jenkins_rsa`, then you might run a command like this:
scp ~/.ssh/jenkins_rsa ubuntu@server.com:~/.ssh
Assuming you're using a Debian-based distribution, you can install git with:
sudo apt-get install git-core
The best way to do this is to follow Jenkins' own tutorial on this, to ensure you have the latest version.
The tutorial for installing Jenkins on Ubuntu is here.
Depending on what version of node you want to run on your machine, you'll need a different version of node and NPM. If the version you want isn't the same as the version your distribution carries, you'll want to use a version manager. There are quite a few tools for this - n[1], Nave[2] and nvm[3] are popular examples, which each have their upsides and downsides. Choose whichever one works best for you.
For the purposes of this article I'll assume the default one works fine for your application:
sudo apt-get install python-software-properties sudo add-apt-repository ppa:chris-lea/node.js sudo apt-get update sudo apt-get install nodejs npm nodejs-dev
We need to install mocha globally so we can run it from any directory. We do this by running:
sudo npm install -g mocha
sudo apt-get install ant
You need to identify the build server so that it can push those tags.
First-off, you need to git the server a name and email address:
git config --global user.email "you@example.com" git config --global user.name "Your Name"
You need to do this so that github or bitbucket will attempt to authenticate you. The name and email should be the same as the name and email used on the github or bitbucket account that the SSH key is associated with.
Assuming you've built your unit tests already on your development machine, the only thing left to do is to build an ant script to allow us to configure the environment before and after the test is ran, using a build.xml file in the root of your codebase. Luckily, I have one prepared! You can add in other `<target>` elements which can describe any preparation you need to make before or after running your tests, by adding them to the `depends` attribute's list in `<target name`"jenkins" />= at the bottom.
<?xml version="1.0" encoding="UTF-8"?> <project name="My Project" default="build" basedir="."> <target name="init" description="Create build folder and subfolders if required"> <echo message="Creating Directories..." /> <mkdir dir="build"/> <mkdir dir="build/testResults"/> </target> <target name="cleanup" description="Remove cruft generated from testing"> <echo message="Cleaning up..." /> <delete includeemptydirs="true" failonerror="false"> <fileset dir="/tmp/node_modules/"> <include name="**" /> </fileset> </delete> <delete includeemptydirs="true" failonerror="false"> <fileset dir="build/testResults"> <include name="**" /> </fileset> </delete> </target> <target name="mocha-jenkins" description="Test framework"> <echo message="Installing Deps ..." /> <exec executable="npm" failonerror="true"> <env key="NODE_PATH" value="/tmp/node_modules/" /> <arg value="install" /> </exec> <echo message="Running the tests ..." /> <exec executable="mocha" output="build/testResults/mocha.xml" failonerror="true"> <env key="NODE_PATH" value="/tmp/node_modules/" /> <arg value="--reporter" /> <arg value="xunit" /> </exec> <echo message="Tests done" /> </target> <target name="jenkins" depends="cleanup,init,mocha-jenkins" /> </project>
You can see above that we make three directories: `build`, `build/testResults`, and `/tmp/node_modules`. These are where mocha's test results are stored.
They'll be used later by Jenkins to determine the result of the test.
The `<env>` tags are used to define where our global node modules are. It's important we move this to somewhere where jenkins has permission. The tmp directory is as good as any!
Now that we have the server all set up, and an ant script ready and working, we need to configure Jenkins to be able to run our tests and report the results. To do that we'll install the following plugins:
`Manage Plugins` -> `Available` and searching for them in the list.
Once they've been installed, Jenkins will restart.
Now we need to create a new "job" to run our test within. You need to click on `New Job`, then give it a name and select `Free-style software project`. For speed, here's an image of my setup (I've expanded all the "advanced" buttons to show all of my settings):
To setup jenkins to read your mocha test result, click on "post-build action" then select "Publish jUnit test result report", then fill in as the image describes.
Well done, Jenkins is configured!
Now all you have to do, is test the build. We can do this within Jenkins by Clicking the "Build Now" link on the left hand side of the page. It should pass (or fail, depending on how good your code is!). If the build passed, it should have pushed a Tag[1] onto the latest revision. If it passed or failed, you should now see a graph in the project page.
A test result graph. The red is failed builds. Happily, there isn't much red.
You're done! You can extend your config to alert you in different ways, run other jobs when builds pass, and many other exciting things. I'll be writing about getting other things working under Jenkins soon.
Over and out!