Skip to content

Instantly share code, notes, and snippets.

@HoverBaum
Last active May 24, 2016 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HoverBaum/d9e7588c0cb5d704e966c780992c9c5b to your computer and use it in GitHub Desktop.
Save HoverBaum/d9e7588c0cb5d704e966c780992c9c5b to your computer and use it in GitHub Desktop.
How I go about testing JavaScript.

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.

Tape

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.

Usage

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.

Test

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

Plan

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();

Getting started

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

Testing front end

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment