New QUnit to JS Test Driver adapter
23. June 2009
In my previous post on QUnit and JS Test Driver I showed how to run your qunit tests with JS Test Driver.
The technique used was to run the tests with qunit, and report either their success or failure to JS Test Driver. This works, but you miss out on the important feedback of exactly which assertions have failed, and why.
This problem has led me to taking a new approach to running qunit tests with JS Test Driver, where I don’t use any of the existing qunit code, and instead just create an interface wrapper that converts qunit style tests and assertions directly into JS Test Driver tests and assertions.
This gives assertion level error reporting, making it much easier to write and debug tests. Essentially this adapter allows you to write native JS Test Driver tests, but using the less verbose qunit syntax.
The new approach also means that qunit lifecycles (setup and teardown) work.
Installing the QUnit Adapter
First up download the equiv.js file, which is required for the qunit same
assertion.
Then download the QUnitAdapter.js file (or copy the code below).
QUnitAdapter.js
(function() {
window.module = function(name, lifecycle) {
QUnitTestCase = TestCase(name);
if (lifecycle) {
QUnitTestCase.prototype.setUp = lifecycle.setup;
QUnitTestCase.prototype.tearDown = lifecycle.teardown;
}
};
window.test = function(name, test) {
QUnitTestCase.prototype['test ' + name] = test;
};
window.expect = function(count) {
expectAsserts(count);
};
window.ok = function(actual, msg) {
assertTrue(msg ? msg : '', actual);
};
window.equals = function(a, b, msg) {
assertEquals(msg ? msg : '', b, a);
};
window.start = window.stop = function() {
fail('start and stop methods are not available when using JS Test Driver.\n' +
'Use jsUnit Clock object to deal with timeouts and intervals:\n' +
'http://googletesting.blogspot.com/2007/03/javascript-simulating-time-in-jsunit.html.');
};
window.same = function(a, b, msg) {
assertTrue(msg ? msg : '', window.equiv(b, a));
};
window.reset = function() {
fail('reset method is not available when using JS Test Driver');
};
window.isLocal = function() {
return false;
};
window.QUnit = {
equiv: window.equiv,
ok: window.ok
};
})();
Save both these files to your project (for example tests/qunit/
).
Configuring JS Test Driver
To run your qunit tests in JS Test Driver you need to configure it to load the adapter before your qunit tests.
Update your jsTestDriver.conf
to load the files:
server: http://localhost:9876
load:
# Add these lines to load the equiv function and adapter in order, before the tests
# (assuming they are saved to tests/qunit/)
- tests/qunit/equiv.js
- tests/qunit/QUnitAdapter.js
# This is where we load the qunit tests
- tests/js/*.js
# And this loads the source files we are testing
- src/js/*.js
Running JS Test Driver with qunit tests
Now we can run JS Test Driver and watch as it runs all our qunit tests!
The tests will run as individual JS Test Driver tests, with the format _Module Name_._Test Name_
.
Example output:
[PASSED] Module 1.test Test 1
[PASSED] Module 1.test Test 2
[PASSED] Module 2.test Test 1
Total 3 tests (Passed: 3; Fails: 0; Errors: 0) (1.00 ms)
Safari 530.18: Run 3 tests (Passed: 3; Fails: 0; Errors 0) (1.00 ms)
Limitations
There are a few limitations on which qunit tests will successfully be converted.
The tests must run synchronously (which means no use of the qunit stop
and start
methods).
If you need to test timeouts, intervals, or other asynchronous sections of code, consider using the jsUnit Clock object to deal with timeouts and intervals.
QUnit DOM
support is not included. Consider avoiding interacting directly with the browser within your unit tests. But if you do need to, you’ll need to create and remove the DOM objects yourself with each test, or the setup
and teardown
methods.