Michael
Michael

Reputation: 10303

How to test client-side code with NodeUnit

This is a follow-up to my previous question.

Suppose I am writing the calculate.js source file with a calculate function to use it in my client-side code:

function calculate(num) {
    return num * 2;
}

Now I would like to test it.

I am using nodeunit as described in this article and export the calculate function (so that tests can invoke it).

function calculate(num) {
    return num * 2;
}

exports.calculate = calculate // Node.js stuff. It won't run in a browser!

The nodeunit tests run OK, but I cannot use calculate.js in my web application any longer since it uses exports.

Now it looks like a catch. Can I fix this problem?

Upvotes: 4

Views: 2413

Answers (5)

keithhackbarth
keithhackbarth

Reputation: 10136

You can actually test isolated jQuery logic within nodeunit itself. For example, here is some tests I wrote for my datepicker library:

/* jshint evil:true */
/* global module, require, DatePair */

var fs = require('fs');
// Some of the plugins use a jQuery variable instead of $
var jQuery = require('jquery');
var $ = jQuery;

// Recreate window and document
var window = { jQuery: jQuery };
var document = window;

// The file is included here:
eval(fs.readFileSync('../lib/js/jquery/plugins/jquery.cookie.js') + '');
eval(fs.readFileSync('../lib/js/jquery.timepicker/jquery.timepicker.js') + '');
eval(fs.readFileSync('../lib/js/bootstrap/bootstrap-datepicker.js') + '');
eval(fs.readFileSync('../homepage/js/datepair.js') + '');

// Initialize DatePair Object
var datePair = DatePair(new Date(), {
    dateStart: $('<input type="text" autocomplete="off">'),
    dateEnd: $('<input type="text" autocomplete="off">'),
    timeStart: $('<input type="text" autocomplete="off">'),
    timeEnd: $('<input type="text" autocomplete="off">')
});

module.exports = {
    'Time Delta Var Is 1 hour' : function (test) {
        test.equal(datePair.getTimeDelta(), 3600);
        test.done();
    },
    'Change Date And Check For 1 Hour Difference' : function (test) {
        datePair.startTime.val("10:00pm").change();
        test.equal(datePair.endTime.val(), "11:00pm");
        test.done();
    },
    'Make End Date Move Up One Day' : function (test) {
        var expectedEndDates = [1];
        datePair.startTime.val("11:00pm").change();
        expectedEndDates.push(parseInt(datePair.startDate.val().split("/")[1], 10) + 1);

        test.ok($.inArray(parseInt(datePair.endDate.val().split("/")[1], 10), expectedEndDates) !== -1);
        test.equal(datePair.endTime.val(), "12:00am");
        test.done();
    },
    'Change To 11:30pm Of Previous Day' : function (test) {
        // Move startTime 1 Day Forward
        datePair.startTime.val("11:00pm").change();
        // Move EndDate 1 Day Backwards
        datePair.endTime.val("11:30pm").change();

        test.equal(datePair.endDate.val(), datePair.startDate.val());
        test.done();
    }
}

See the full code + library here: https://github.com/keithhackbarth/jquery-datetime-picker

Upvotes: 0

hurrymaplelad
hurrymaplelad

Reputation: 27745

nodeunit-browser-tap + Testling is another option if you're set on nodeunit.

  • The Testling npm package gets you command line output for tests run in a local browser.
  • Testling.com gets you free cross browser CI if you host on GitHub.
  • The browser-tap wrapper gets you nodeunit output that Testling understands.

Upvotes: 2

hurrymaplelad
hurrymaplelad

Reputation: 27745

Karma runner has a nodeunit adapter to run nodeunit tests in browsers and PhantomJS. Here's an example test entrypoint and Gruntfile using Browserify to run tests written in CommonJS modules (exports).

Upvotes: 2

Alfred
Alfred

Reputation: 61771

Running tests in the browser

If you wish to use a CommonJS format for your test suites (using exports), it is up to you to define the CommonJS tools for the browser. There are a number of alternatives and its important it fits with your existing code, which is why nodeunit does not currently provide this out of the box.

I think you should have a look at Browserify to accomplish this.

Browserify

Make Node.js-style require() work in the browser with a server-side build step, as if by magic!

Mocha

Mocha is a simple, flexible, fun JavaScript test framework for Node.js and the browser.

I think you should have a look at Mocha created by TJ (Express.js' author) which I like very much (better than nodeunit which I used in the past). With Mocha you can easily do code coverage, watch-mode, notifications and as a big plus Mocha is more maintained.

Upvotes: 2

ssmithstone
ssmithstone

Reputation: 1209

Use a non-Node.js testing framework like jasminebdd or jstestdriver.

Upvotes: 3

Related Questions