Let's Make a Framework: More Tests

2010-12-23 00:00:00 +0000 by Alex R. Young

Welcome to part 43 of Let's Make a Framework, the ongoing series about
building a JavaScript framework.

If you haven't been following along, these articles are tagged with
lmaf. The project we're creating is called Turing.

Over the last few weeks we've built a test framework based on the
CommonJS assert module, a suitable test runner, and started converting
Turing's tests to use it. The test framework is called Turing

JavaScript Testing

I get a lot of questions about JavaScript tests, so before continuing
converting Turing's tests I'm going to just explain a little bit about
the basics behind JavaScript testing.

If you're primarily a front-end developer, a lot of the innovative new
work in JavaScript testing might appear confusing. The needs of
server-side testing and client-side diverge, so it's perfectly
acceptable to use a different testing framework for each part of your

According to our 2010 JavaScript
Qunit is the most popular test framework. So you could use Qunit for your browser tests, and the
server-side developers could use something like
nodeunit or jasmine.

There are different types of test libraries. The one we've been
developing on this tutorial series is a unit
framework. The
assert module defined in Unit Testing/1.0 by CommonJS is an example of a large part of a unit
testing framework.

Libraries like Jasmine are Behavior Driven

(BDD) libraries. Some frameworks like Cucumber take this to another extreme, where tests are written as executable

There are more flavours of test libraries, and some become fashionable
and widely used. Because tests can be useful documentation for another
developer, if you're writing an open source project it might be a good
idea to use what your community uses. If you're writing a jQuery plugin,
why not use Qunit?

If you're working on your own project or in a small team, the choice of
test libraries can seem bewildering. You could fall back on the CommonJS
modules and treat that as the "standard" way to write tests, as it's
likely that other people will be able to understand your tests. The
point is to actually write tests in a way that makes you feel productive
-- some people get bogged down with the abstraction of BDD libraries, other people find that style of testing can help communicate business
logic to clients or managers.

Test Conversion

I've converted the core tests to Turing Test (from

The enumerable tests demonstrated where using assert.equal
or assert.deepEqual are appropriate:

exports.testEnumerable = {
  'test array iteration with each': function() {
    var a = [1, 2, 3, 4, 5],
        count = 0;
    turing.enumerable.each(a, function(n) { count += 1; });
    assert.equal(5, count, 'count should have been iterated');

  'test array iteration with map': function() {
    var a = [1, 2, 3, 4, 5],
        b = turing.enumerable.map(a, function(n) { return n + 1; });
    assert.deepEqual([2, 3, 4, 5, 6], b, 'map should iterate');

The second test here need deepEqual to check the arrays are
the same. It's important to remember which type of equal to use when
writing CommonJS assertions.

The OO

had to be reworked slightly to suit CommonJS module constraints in the

Running All Tests

I've made
run.html run all of the tests in the browser. It was actually very easy to do, I
just had to list all of the unit test files in script tags:

Future Updates

When I started writing the Turing Test tutorials I mentioned I'd like to
be able to run all tests, in a similar way to Qunit. This kind of works
now, but isn't presented particularly well. The test runner we've built
doesn't summarise all of the tests, and the layout isn't quite clear

Turing Test also needs to display benchmarks, and according to our
survey 12% of people benchmarking code use unit tests as an indicator of

I'm pleased with the results now everything has been converted to
CommonJS tests. As usual, more next week!