Getting Started

This page will guide you through all the things you need to do to start writing Specify tests for Node and Browsers (the instructions should be similar to other platforms). It assumes you’ll be using the Sweet.js DSL and the built-in assertion library.

Note

This tutorial does not assume any previous knowledge of Sweet.js or Node.js, only JavaScript. However, you’ll need to have Node.js installed in your system.

Installing

  1. The first step is installing Node.js. Follow the instructions in the Node.js download page for your OS.

    After finishing this step, you should have both the node and npm applications available in your system. Check the command line to see if they’re there:

    $ node --version
    v0.10.35
    
    $ npm --version
    1.4.28
    

    Warning

    When installing Node.js from the system package manager in some Linux systems (e.g.: Ubuntu), the Node binary will be nodejs instead of node, to avoid conflict with another package with the same name. In Debian-based systems, you can install the nodejs-legacy package, or you can symlink the Node binary as node somewhere in your path manually.

  1. The second step is installing the Sweet.js package. We’ll be using Sweet.js macros to write tests and assertions with a more expressive and clean syntax than what JavaScript provides.

    To install Sweet.js, run the following command in your project directory:

    $ npm install sweet.js@0.7.1
    
  2. After installing Node and Sweet.js, we can install the Specify framework, which will provide everything else that we need for writing tests.

    To install the Specify framework, run the following command in your project directory:

    $ npm install specify-framework
    

Using Specify in the Browser

We’ll be using Node modules for writing modular test files, and loading the Specify framework. Since Browsers don’t implement Node modules by default, we’ll need another compile step to transform these modules in a format that the Browser can understand. For this, we’ll use the Browserify tool.

To install Browserify, run the following command in your project directory:

$ npm install browserify

Writing tests

The idiomatic way of writing tests in Specify is very similar to Mocha, but the Sweet.js DSL reduces some of the boilerplate. In Specify, you organise your tests into Suites, which may contain many definitions and suites, and definitions, which may contain many assertions related to a particular functionality.

As an example, let’s consider the add.js module:

1
2
3
4
5
6
7
8
9
function add(a, b) {
  if (b === 0) {
    return a;
  } else {
    return add(a + 1, b - 1);
  }
}

module.exports = add;

A specification for this module could look like this:

add(a, b)
  • When adding 0 to any value, the result is that value.
  • When adding two positive numbers, the result is always greater than both.

We can capture this specification by writing a test file for the add.js module. Let’s call it test-add.sjs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// First we load the `add` module
var add = require('./add');

// Then we define the specification
module.exports = spec 'add(a, b)' {
  it 'when adding 0 to any value, the result is that value.' {
    add(4, 0) => 4;
    add(0, 5) => 5;
  }

  it 'when adding two positive numbers, the result is always greater than both.' {
    add(4, 5) => 9;
    add(3, 2) => 5
  }
}

test-add.sjs does two things: first it loads the add module that we want to test. Then it exports a Suite object (which is created by the spec '<description>' { <definitions or suites...> } syntax). Each it '<description>' { <javascript statements...> } creates a new definition inside the spec group, and corresponds to one of the bullet points in the specification we drafted above.

The <expression> => <expected result> syntax is added by the Specify assertion module, and allows one to make (deep) equality assertions in tests in a clean and concise manner.

Note

require(...) and module.exports are part of Node’s module system, which is a better take on the CommonJS Modules specification. If you’re not familiar with it, you can read the Node Modules to Rule Them All article, which describes module systems in JS, and Node modules in particular.

Running a test module

Before running the test module we just wrote, we’ll need to compile it. To do that, we can type the following in the command line:

$ node_modules/.bin/sjs --module specify/macros --output test-add.js test.sjs

And since we’re going to be running it a bit, we can put it in a package.json file on the root of the project, and have npm work as a task runner. To do so create a package.json file with the following contents:

1
2
3
4
5
{
  "scripts": {
    "compile-tests": "node_modules/.bin/sjs --module specify/macros --output test-add.js test.sjs"
  }
}

This way you can type npm run compile-tests in the command line to invoke the compilation command. You can also use Grunt, Make, or any other task runner tool you feel comfortable with.

Writing the runner

To run these tests we’ll write a simple JavaScript module that will do it for us, this way this module can be used to run the tests in Node, the Browser, in CI servers like Testling, etc.

Create a file called run-tests.js with the following content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// First we load the Specify framework.
var specify = require('specify');

// Then we load the reporter we want to use to present the results of
// running the test. The `spec` reporter displays these information
// as a hierarchical specification-like format.
var reporter = specify.reporters.spec();

// We also need the list of suites that we want to run.
var suites = [
  require('./test-add')
];

// And finally, we pass the list of suites and the reporter to the
// built-in runner:
specify.runWithDefaults(suites, reporter);

You may now run the tests in the command line by invoking node run-tests.js.