Testing your application can seem like a huge undertaking, but it doesn’t have to be. Setting up testing is easy, and lets you write your tests as you write your code (or vice-versa if you’re using TDD) and prevents you from gaining testing debt in your source code. In this brief guide I’m going to demonstrate a quick and easy way to setup NodeJS unit testing complete with Travis CI.
Preface
This guide expects that you’re hosting your code on GitHub. If you aren’t the steps around committing and pushing your code, as well as those around setting up Travis CI won’t apply to you. Everything else should though!
Installing Jasmine
First off we need to install Jasmine which is the unit testing library. It contains both unit tests runners and the assertions that make up tests. Ensure that your project already has a package.json
file. If it doesn’t you can run npm init
in your project root directory to create one.
npm install -g jasmine
This installs the jasmine cli which we’ll use to initialize the project for testing. You may need to sudo
this command.
Setting up your Project for Testing
Now that jasmine is installed lets setup the project for testing by running the following in your project root directory:
jasmine init
This will create a directory called spec
and within it the file spec/support/jasmine.json
. This file configures how tests are run. Opening it up we see the following:
{ "spec_dir": "spec", "spec_files": [ "**/*[sS]pec.js" ], "helpers": [ "helpers/**/*.js" ] }
This tells jasmine that your tests are located in the spec
directory and have names that end in spec.js
or Spec.js
. It also declares a folder for finding optional helpers. This is actually all of the configuration you need! So let’s go ahead and write some tests.
Writing a basic unit test
First, let’s start off with our code file index.js
. This file is simply going to print out “Hello World!” by getting a string from the getStringToPrint()
function:
function getStringToPrint() { return "Hello World!"; } console.log(getStringToPrint()); module.exports = { getStringToPrint: getStringToPrint };
Note that we export the getStringToPrint()
function so that it’s available later in our tests.
Now lets create a unit test for this file:
var index = require('../index.js'); describe("index", function () { it('should print Hello World!', function () { expect(index.getStringToPrint()).toBe('Hello'); expect(index.getStringToPrint()).toMatch(/World/); }); });
You can see how Jasmine makes your unit tests descriptive of what we’re testing. The code itself makes it pretty clear what’s being tested and what the goal is. This spec includes two test cases: one that checks if the string returned is Hello
and the other checks if the string returned matches the regular expression /World/
.
Now lets run the test and see what happens:
Started F Failures: 1) index should print Hello World! Message: Expected 'Hello World!' to be 'Hello'. Stack: Error: Expected 'Hello World!' to be 'Hello'. at Object.<anonymous> (/Users/mblouin/Documents/work/nodetesttutorial/spec/indexSpec.js:5:36) 1 spec, 1 failure Finished in 0.007 seconds
It failed! Of course it did, the text returned by getStringToPrint()
doesn’t match the first test, but it would match the second one. We could either update the string in the first test or update the regular expression in the second one and get rid of the first. Let’s fix it and try again:
Started . 1 spec, 0 failures Finished in 0.004 seconds
Success! We now have working tests. Now lets setup continuous integration with Travis CI.
Add Travis CI for continuous integration
Unit testing is great by itself, but the goal is to setup a system that automatically runs tests for you and informs you whether you’ve broken something. This way you always know whether your repo is working or not. Additionally if you get a pull request on GitHub Travis will automatically tell you whether the incoming changes work or break your project.
Let’s start by adding a test
command to our package.json
:
{ "name": "nodetesttutorial", "version": "1.0.0", "description": "A tutorial for unit testing in NodeJS.", "main": "index.js", "scripts": { "test": "jasmine" }, "author": "Michael Blouin", "license": "Apache-2.0" }
Note line 7 where we define that our tests are running by running the command jasmine
in the current directory. Now that this command is in package.json
you can run the tests by running npm test
in the current directory. Cool!
The next step is to tell Travis CI what to do when it goes to test the project. This is done by adding a .travis.yml
file to the root directory of the project:
language: node_js before_script: - npm install -g jasmine node_js: - "0.12" - "0.11" - "0.10" - "iojs"
Here we tell Travis that the language we’re testing is nodejs. We tell it before it tries to test it should install jasmine globally, and then we give it a whole bunch of versions of NodeJS to test against. The last line tells it to test against the most recent version. This way we can ensure that not only does our code work for the most recent version, but that it works for a whole bunch of other versions as well!
Next you need to create a repository on GitHub and push the code. Once you have a repository run the following to add your changes and push them. If you already had git setup for this project you can skip the git init
and git remote
commands.
git init . git remote set-url origin <your_git_repo_url> git add index.js spec package.json .travis.yml git commit -m "Adding project files" git push --set-upstream origin master
That’s it! Now your changes are saved in GitHub. Now let’s connect the dots with Travis CI. Got to travis-ci.org and attach it to your GitHub account. Once you’ve attached your GitHub account setup your project by clicking on the small +
icon (pictured to the right).
Find your repo in the list (you may need to click the sync button at the top of the page if you don’t see it) and click the toggle switch.
Now Travis is enabled! But it will only try and build the code when you make a change, so let’s go ahead and do that by adding a README with your new tests passing badge! In Travis CI select the project you enabled by clicking on its name. On this page you’ll see a build | unknown
badge. Click this badge and select “markdown” in the popup. Copy the text in the box.
Now go to your project and add a README.md
(make sure to paste in your markdown on line 3):
# Node JS Unit Tests! <<Place your copied markdown here>> This project demonstrates how easy and awesome it is to setup NodeJS unit testing with Travis CI!
Now add and push your changes:
git add README.md git commit -m "Adding README" git push
Now go to your GitHub page and you’ll see your badge:
If the state is unknown then your test hasn’t been run yet. Click on your badge and you’ll be taken to the Travis CI page where you can watch your tests be run. I recommend clicking around a bit here and exploring your test output – it’s really quite neat.
Going back to your GitHub page after your tests complete and you’ll see a nice green build | passing
badge. Good job! By testing your code you’ve made the world a better place!
Let me know in the comments if this was useful, and be sure to leave a rating below. You can find the code for this tutorial on GitHub. Thanks for reading!
No comments yet.