Everything should be tested. Well everythings that is more than playing around. Tests make your code better, more reliable and help find bugs. Though tests do add a massive overhead to changing your code. And quite honestly I have probably spend more time writing tests then code that they test. But in the end it was always worth it because they find bugs and tell me what I can rely on to work.
I like the "KISS" princliple, not just because of its name, so let us keep it simple stupid
(and yes I just researched wether or not to put a comma there).
A lot of testing Frameworks out there introduce a lot of overhead and semantics to your code. Thus I came to use Tape which produces TAP output.
Tape is awesome and simple, let us look at their sample code and run it:
var test = require('tape');
test('timing test', function (t) {
t.plan(2);
t.equal(typeof Date.now, 'function');
var start = Date.now();
setTimeout(function () {
t.equal(Date.now() - start, 100);
}, 100);
});
$ node example/timing.js
TAP version 13
# timing test
ok 1 should be equal
not ok 2 should be equal
---
operator: equal
expected: 100
actual: 107
...
1..2
# tests 2
# pass 1
# fail 1
As you can see above all a test is, is a function called test
which takes a string to identify the test and a function which is the test. This function gets a t
on which you can call a few things.
Probably the most important things you can do is test things. Tape provides many methods for that. The most important are probably:
- t.ok(), check if a value is truthy
- t.equal(), check if values are equal to each other
- t.throws(), check for errors being thrown
The only thing you really need to keep in mind is that you either need to tell Tape how many tests to expect or explicitly tell it that you are finished.
//We will do 3 tests.
t.plan(3);
//We are finished testing.
t.end();
First we need Tape and I suggest you also get tape-spec to make the output a bit prettier.
npm install --save-dev tape tape-spec
Next create a script in you package.json
.
"scripts": {
"test": "node ./node_modules/browserify/bin/cmd.js test/test.js | tap-spec",
}
For this I made a single entry point for all my tests in test/test.js
. Tape will run them and since it outputs to the stdout we just pipe that into tape-spec
which will make it look prettier.
Now you can simply
npm test
Tape can generally test anything JavaScript. The problem comes when you expect window
or something to be there or want to operate on the DOM. There are multiple solutions to this. The simple and small one which worked best for me is tape-run. You also browserify your test or use another framework to achieve the same result.
npm install --save-dev tape-run tap-spec
"scripts": {
"test": "node ./node_modules/browserify/bin/cmd.js test/test.js | node ./node_modules/tape-run/bin/run.js | tap-spec",
}
Simply pipe your tests into tape-run and then into tape-spec. What tape-run actually does is run your tests inside a headless browser and then pipe the results to stdout. Using browserify and some other solutions you will have to open and close a browser to see the results.