Home

Awesome

jam3-testing-tools

This is a brief introduction to some common practices when it comes to testing frontend modules, and test-driven development. The goal is to test while you develop the module, so that you end up with a test for each feature you've added.

contents

global tools

The first step is to install some global tools that we will use for testing and development. Usually it's recommended to install these tools locally (per-module), but we will get to that a bit later. For now, global tools help us get up and running a bit quicker.

# installs some global tools
npm i beefy nodemon browserify faucet -g

<sup>TIP - npm i is shorthand for npm install</sup>

tape

Many modules are generic and not tied specifically to NodeJS or the browser. For example, a rgb-to-hsl color conversion module does not need to rely on the DOM or on any OS-level features. For these modules we can use tape, which works in Node and the browser.

First, stub out a test.js file. If you plan to have many tests and assets, you might want to put this in a tests folder. Some tools like module-generator might already stub this out for you.

var rgb2hsl = require('./')
var test = require('tape')

test('converts rgb colors to hsl', function(t) {
    //... unit tests here
    t.end()
})

Then, you can update the scripts field of your package.json. This might already be done if you used a module generator.

  "scripts": {
    "test": "node test.js"
  }

You can now test the module with npm test (alias for npm run test), or just running node test.js.

nodemon

When working with a generic module like rgb-to-hsl, it's usually faster to develop it in a terminal than to set up HTML and a browser. During development, we can use nodemon to live-reload the test file. The process looks like this:

# start listening to our test.js file
nodemon test.js

Now when you save the test.js file, it will auto-reload the terminal script and print the results.

adding unit tests

Now you can start developing your core module, and testing while you do so. For example, your tests might look like this after a few iterations. We use equal to compare two values with strict equality, and then deepEqual to compare arrays and objects. Make sure to end tests with t.end().

You can read more about tape, async tests, and other features here.

var rgb2hsl = require('./')
var test = require('tape')

test('converts rgb colors to hsl', function(t) {
    var color = [125, 125, 125]
    t.equal(rgb2hsl(color).length, 3, 'should return [H, S, V] array')
    t.equal(rgb2hsl(color)[1], 0, 'should be zero saturation')
    t.deepEqual(rgb2hsl([255, 0, 0]), [0, 100, 50], 'should be pure red')
    //.. some other tests..
    t.end()
})

beefy

The above nodemon tool won't work with browser code. If we're making a browser-specific module (like dom-css) we can do some initial development with beefy using the following command:

#run beefy and open the browser
beefy test --open

<sup>TIP - beefy foo is shorthand for beefy foo.js</sup>

This will serve the file at localhost:9966. Now you can save the test.js file and reload the browser to see the results in the console. Beefy is useful for rapid prototyping, and modules that are harder to automate (like WebGL code, user interactions, etc). It's also a good way to deliver demo / example code to the user.

It's typically a good idea to save these tools locally, so that anybody cloning your repo is running the same versions you are.

npm install beefy browserify --save-dev

Users cloning the repo won't be able to run beefy test.js from terminal. Instead, locally-installed tools are run via npm-scripts (it first looks inside node_modules). So now your package.json looks like this:

  "scripts": {
    "test": "beefy test.js --open"
  }

Now running npm test will open beefy.

smokestack

Although beefy is pretty good, it would be better if we could automate our tests and eventually have them running in the cloud (like with zuul and SauceLabs). It can also be tedious to have to open DevTools just to see the test results.

One alternative to beefy is to use smokestack for automation. This launches Chrome or FireFox, so it allows us to test the full range of Web APIs (WebGL, WebAudio, etc).

We will install it locally, as well as a couple of other tools:

npm install smokestack tap-closer browserify --save-dev

Then our tests are run like so:

  "scripts": {
    "test": "browserify test.js | tap-closer | smokestack"
  }

Now when we run npm test it will run the tests in a browser and print the result to the console. Eventually, these modules can be updated to run the tests in the cloud on a variety of browsers. An example is dom-css, which uses SauceLabs for testing and Travis for continuous integration.

You may also be interested in testling which has similar goals, except focuses more on PhantomJS (i.e. runs heedlessly, but doesn't support full range of browser capabilities).

pretty-printing

img

We can use faucet or tap-spec to pretty-print the test results, making them coloured and more compact. Example:

nodemon test | faucet 

<sup>needs a globally-installed faucet</sup>

If you use it in your package.json, you should install it locally.

npm install faucet --save-dev

For example, if we are using smokestack:

  "scripts": {
    "test": "browserify test.js | tap-closer | smokestack | faucet"
  }

alternatives