This chapter covers
- Why testing is important
- What unit testing means
- Installing QUnit
- Testing your JavaScript code with QUnit
- How to create a complete test suite with QUnit
14.1 Why is testing important
14.1.1 Why unit testing
- Attest that the code returns expected results given specific inputs.
- Discover the highest number of defects in an early stage (related to the previous point).
- Improve the design of the code.
- Identify units that are too complex.
14.1.2 Frameworks for unit testing
JavaScript
QUnit
Mocha
Jasmine (behavior-driven development)
14.2 Getting started with QUnit
14.3 Creating tests for synchronous code
QUnit.test(name, test)
Parameters
name (String)
test (Function)
Returns
undefined
QUnit.test('My first test', function(assert) {
//Code here...
});
expect(total)
Parameters
total (Number)
Returns
undefined
QUnit.test('My first test', function(assert){
assert.expect(0);
});
14.4 Testing your code using assertions
14.4.1 equal(), strictEqual(), notEqual(), and notStrictEqual()
equal(value, expected[, message])
Parameters
value (Any)
expected (Any)
message (String)
Returns
undefined
function sum(a, b) {
return a + b;
}
QUnit.test('My first test', function(assert) {
assert.expect(3);
assert.equal(sum(2, 2), 4, 'Sum of two positive numbers');
assert.equal(sum(-2, -2), -4, 'Sum of two negative numbers');
assert.equal(sum(2, 0), 2, 'Sum of a positive number and the neutral
element');
});
strictEqual(value, expected[, message])
Parameters
value (Any)
expected (Any)
message (String)
Returns
undefined
assert.equal($.trim(' '), '',
'Trimming a spaces-only string returns an empty string');
assert.strictEqual($('input:checked').length,
$('input').filter(':checked').length,
'Filtering elements in advance or later produce the same number of
elements');
assert.notEqual($('input:checked'), $('input').filter(':checked'),
'Two jQuery objects are different unless they point to the same memory
address');
assert.notStrictEqual(new Array(1, 2, 3), [1, 2, 3],
'Two arrays are different unless they point to the same memory address');
14.4.2 The other assertion methods
An overview of other assertion methods provided by QUnit
Method | Description |
---|---|
deepEqual(value, expected[, message]) | |
notDeepEqual(value, expected[, message]) | |
propEqual(value, expected[, message]) | |
notPropEqual(value, expected[, message]) | |
ok(value[, message]) |
function isEven(number) {
return number % 2 === 0;
}
assert.strictEqual(isEven(4), true, '4 is an even number');
assert.ok(isEven(4), '4 is an even number');
14.4.3 The throws() assertion method
throws(function[, expected][, message])
Parameters
function (Function)
expected (Object|Function|RegExp)
message (String)
Returns
undefined
function isEven(number) {
if (typeof number !== 'number') {
throw new Error('The passed argument is not a number');
}
return number % 2 === 0;
}
assert.throws(
function() {
isEven('test');
},
new Error('The passed argument is not a number'),
'Passing a string throws an error'
);
14.5 How to test asynchronous tasks
async
Parameters
none
Returns
A unique resolution callback function.
QUnit.test('Testing asynchronous code', function(assert) {
var $fixtures = $('#qunit-fixture');
assert.expect(4);
assert.strictEqual(
$fixtures.children().length,
0,
'The children of qunit-fixtures are 0'
);
var firstCallback = assert.async();
window.setTimeout(function() {
assert.ok(isEven(4), '4 is even');
firstCallback();
}, 500);
var secondCallback = assert.async();
$fixtures.load('test.1.html #qunit', function() {
assert.ok(
true,
'File test.1.html has been successfully loaded'
);
assert.strictEqual(
$fixtures.children().length,
1,
'The elements appended to qunit-fixtures are 1'
);
secondCallback();
});
});
14.6 noglobals and notrycatch
QUnit.test('Testing the noglobals option', function(assert) {
assert.expect(1);
window.bookName = 'jQuery in Action';
assert.strictEqual(bookName, 'jQuery in Action', 'Strings are equal');
});
QUnit.test('Testing the notrycatch option', function(assert) {
assert.expect(1);
assert.strictEqual(add(2, 2), 4, 'The sum of 2 plus 2 is equal to 4');
});
14.7 Group your tests in modules
QUnit.module(name[, lifecycle])
Parameters
name (String)
lifecycle (Object)
Returns
undefined
QUnit.module('Core');
QUnit.test('First test', function(assert) {
assert.expect(1);
assert.ok(true);
});
QUnit.module('Ajax');
QUnit.test('Second test', function(assert) {
assert.expect(1);
assert.ok(true);
});
14.8 Configuring QUnit
The configuration properties of QUnit.config
Name | Description |
---|---|
altertitle | |
autostart | |
hidepassed | |
moduleFilter | |
reorder | |
requireExpects | |
testId | |
testTimeout | |
scrolltop | |
urlConfig |
QUnit.config.hidepassed = true;
QUnit.config.requireExpects = true;