Jasmine, Coffeescript, and Require.js, Part I.

Having spent the better part of an afternoon wrangling a jasmine test suite written in coffeescript into AMD-readiness, the steps needed to get all parties playing well with one another seem worth sharing. I owe a huge debt of gratitude to Dave Geddes’ AMD Testing repository for tying require.js and jasmine together.

|-- Makefile
|-- src
|   |-- plugins
|   |   `-- cs.js
|   `-- libs
|       `-- CoffeeScript.js
`-- test
    |-- runner.js
    |-- spec
    |   |-- fixtures
    |   `-- units
    |       `-- a.spec.coffee
    `-- lib
        |-- consoleJasmineReporter2.js
        `-- jasmine-1.1.0.rc1

The test directory is a clone of the jasmine example in the AMD Testing repo, but a few adjustments are required to adapt the test runner (runner.js) for use with coffeescript:

var requirejs = require('requirejs');

// tell require.js to operate out of the root directory and load
// coffeescript dependencies
requirejs.config({
  baseUrl: '../',
  nodeRequire: require,
  paths: {
    fixtures      : 'test/spec/fixtures'
  , units         : 'test/spec/units'
  , cs            : 'src/plugins/cs'
  , CoffeeScript  : 'src/libs/CoffeeScript'
  }
});

// make define available globally like it is in the browser
global.define = require('requirejs');

// make jasmine available globally like it is in the browser
global.describe = require('./lib/jasmine-1.1.0.rc1/jasmine').describe;
global.it = require('./lib/jasmine-1.1.0.rc1/jasmine').it;
global.expect = require('./lib/jasmine-1.1.0.rc1/jasmine').expect;

// bring in and list all the tests to be run
var specs = [
  'cs!units/a.spec'
]

requirejs(specs, function () {
  var jasmine = require('./lib/jasmine-1.1.0.rc1/jasmine').jasmine;
  var ConsoleJasmineReporter2 = require('./lib/consoleJasmineReporter2').ConsoleJasmineReporter;
  jasmine.getEnv().addReporter(new ConsoleJasmineReporter2());
  jasmine.getEnv().execute();
});

The runner is configured to load a.spec.coffee and any additional specs declared in the specs array into jasmine and report the results.

Before testing, any specs that aren’t already written as AMD modules will need to be adapted. Using require.js, the general format looks something like this:

# in spec/units/a.spec
define [
  'dependency'
], (dep) ->
  describe 'a coffee spec', ->
    it 'uses dependency', ->
      expect(dep).toBeDefined()

    it 'passes', ->
      expect(2+2).toEqual(4)

Once all specs have been written and added to the runner, the entire test suite can be executed using node:

$ cd test && node runner.js


Update: I’ve expanded my test harness to support tests written for Backbone and jQuery.**

Let’s keep in touch

Reach out on Twitter or subscribe for (very) occasional updates.

Hey, I'm RJ: digital entomologist and intermittent micropoet, writing from the beautiful Rose City.