There are lots of different ways to get started with unit testing in JavaScript. Today, we’ll look at a simple way to get started: Mocha, a popular unit testing engine. We’ll just look at the vanilla version of Mocha (I suppose the black version would be a more appropriate metaphor in this case). You can make your test cases easier to read by making them read more like an English sentence with packages like Chai, but we’ll leave that for another day.
Prerequisites for this tutorial:
– Node is installed on your machine (how to install node)
– NPM is installed on your machine (should come with Node)
Go ahead and create a directory in your root directory (C:\
or ~
) or your code directory named unit-testing
. Create a file called test.js
Do an npm install mocha
there. Then npm init
, putting in whatever values you like for the name. Make sure that the test command is mocha
Now, run npm test
. You should see something like this:
Okay, it’s passing, but that’s because we don’t have any tests. Let’s fix that. We’ll create a simple adding machine that will tell us the sum of two numbers. A trivial task, but we’re here to learn unit testing, not show off our amazing JS skills. Create a file named adding-machine.js
and put in this code:
function addingMachine (number1, number2) {
return (number1 + number2);
}
// We need to export this so our test file can see it, so add this also:
module.exports = addingMachine;
Now, switch over to your test.js
file and let’s add some test. First, you’ll want to add the assert library, which is how you’ll tell mocha what to expect: const assert = require('assert');
. Then, you’ll require the program you’re testing: const addingMachine = require('./adding-machine');
. Now, let’s actually add some tests.
We’ll start with a describe
, which is a way to group your tests:
describe('addingMachine', function() {
// your tests will go here
});
This is so that your tests neatly fall under the describe and when reading output you can see that those tests are describing the adding machine. It might not seem that important, but if you’re testing a whole bunch of modules at the same time (say, in your build system), having a well-structured test suite is a great benefit. Okay, now let’s actually write a test:
it('should return 2 as the sum of 1 and 1', function () {
assert.equal(2, addingMachine(1, 1));
});
When we use equal
, we’re telling mocha to expect that two inputs of the equal function should be equal. (Wow, I’m sure you’d never have guessed!) So, in this case, we’re saying that the results of putting 1 and 1 into the adding machine should equal the first argument, 2.
Now run npm test
and you should see this:
Great! The test passed. If yours didn’t pass, check to make sure that your code matches mine. You can also use console.log
in both the test.js file and the adding-machine.js file to check your inputs and arguments.
This is a fine test case, but it’s not enough. If the code for the adding machine had been return (number1 + number1)
, this test still would have passed, so it’s important that we check inputs that are different. Let’s do it!
it('should return 11 as the sum of 3 and 8', function () {
assert.equal(11, addingMachine(3, 8));
});
Run npm test
again, it should pass. We should also check numbers that have special properties to make sure that addingMachine handles them the way we expect:
it ('should handle zero properly, returning 1 as the sum of 0 and 1', function () {
assert.equal(1, addingMachine(0, 1));
});
it ('should handle negative numbers properly, returning 5 as the sum of 10 and -5', function () {
assert.equal(5, addingMachine(10, -5));
});
Now, we’ve got a good test suite going. Here’s where your files should be at this point:
test.js
:
const assert = require('assert');
const addingMachine = require('./adding-machine');
describe ('addingMachine', function () {
it ('should return 2 as the sum of 1 and 1', function () {
assert.equal(2, addingMachine(1, 1));
});
it('should return 11 as the sum of 3 and 8', function () {
assert.equal(11, addingMachine(3, 8));
});
it ('should handle zero properly, returning 1 as the sum of 0 and 1', function () {
assert.equal(1, addingMachine(0, 1));
});
it ('should handle negative numbers properly, returning 5 as the sum of 10 and -5', function () {
assert.equal(5, addingMachine(10, -5));
});
});
adding-machine.js
:
function addingMachine (number1, number2) {
return (number1 + number2);
}
Next time, we’ll take a look at how to expand our test suite and handle unexpected inputs.