Assertions are the core of software testing because they allow you to verify that your code is working as expected. QUnit provides numerous methods to test your expectations that can all be accessed within a test through the assert parameter passed to the function passed to QUnit.test().
We’ll start our overview of the assertion methods by covering four of them.
equal(), strictEqual(), notEqual(), and notStrictEqual()
In this section we’ll cover four of the methods provided by QUnit. The first method we want to introduce is equal().
Method syntax: equal | |
---|---|
equal(value, expected[, message]) | |
Verify that the value parameter is equal to the expected parameter using a nonstrict comparison (==). | |
Parameters | |
value | (Any) The value returned by a function or a method, or stored in a variable to verify. |
expected | (Any) The value to test against. |
message | (String) An optional description of the assertion. If omitted, the message shown is “okay” in case of success and “failed” in case of failure. |
Returns | |
undefined |
The description of the assertion, the message parameter, is optional but we suggest that you always set it.
To give you an idea of how to use this method, let’s look at a simple example. Imagine you created a function that sums two numbers passed as arguments. The definition of such a function in JavaScript would be like the following:
function sum(a, b) {
return a + b;
}
With the sum() function in place, you want to verify that it works correctly. To do that employing the equal() method, you can write a test like this:
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');
});
You can run the test opening the file lesson-14/test.1.html or accessing the relative JS Bin.
Running the previous test gives you confidence that your code works properly and your function is robust. But is this the case? As it turns out, it isn’t. What if you add the following assertion to your test? (Remember to update the argument passed to assert .expect() accordingly.)
assert.equal(sum(-1, true), 0, 'Sum of a negative number and true');
This assertion succeeds because JavaScript is a weakly typed language, so true is equal to 1. Therefore, summing -1 and true gives 0 as a result.
In addition to the issue of passing a Boolean, what will happen if you pass a number and a string like "foo" to sum()? In this situation your function will treat both parameters as strings and will concatenate them. Sometimes this may even be the expected result, but usually you want to explicitly deal with such cases. For example, you may want to raise an exception if one or both of the parameters aren’t of type Number or convert them before performing the sum. Before we start discussing how to deal with exceptions and taking into account complex cases, let’s introduce another assertion method QUnit has to offer: strictEqual().
The strictEqual() method is similar to equal() with the exception that it performs a strict comparison between the actual and the expected values. Its syntax is shown here.
Method syntax: strictEqual | |
---|---|
strictEqual(value, expected[, message]) | |
Verify the value parameter is equal to the expected parameter using a strict comparison (===). | |
Parameters | |
value | (Any) The value returned by a function, a method, or stored in a variable to verify. |
expected | (Any) The value to test against. |
message | (String) An optional description of the assertion. If omitted, the message shown is “okay” in case of success and “failed” in case of failure. |
Returns | |
undefined |
For the sake of using strictEqual() with the simple sum() function you created, let’s replace the previous assertion with one where you compare the sum of two numbers with the Boolean value false (you can also update all the other assertions to use strictEqual()):
assert.strictEqual(sum(-2, 2), false, 'Sum of a negative and a positive
number is equal to false');
Refreshing the HTML page will present you with an error. The test is able to detect that the actual and expected values aren’t equal. But using this kind of assertion (that isn’t very useful to test the function), your test is failing, which isn’t what you want. The idea should be to verify that the sum of two numbers is not equal to a Boolean (false in this case), and if this happens your assertion has to succeed.
For such situations where you want to assert that a value is not equal or strictly equal to another, you can employ the counterpart of the methods you’ve seen: notEqual() and notStrictEqual().
Update the previous assertion in order to see if your test succeeds:
assert.notStrictEqual(sum(-2, 2), false, 'Sum of a negative and a positive
number is not equal to false');
This time refreshing the HTML page will correctly execute all four assertions and your test will succeed.
The complete and updated version of the page is shown in the following listing. It’s available in the file lesson-14/test.2.html of the source provided with this app and as a JS Bin.
Listing 14.2. The use of strictEqual() and notStrictEqual()


Up to this point, we’ve only discussed how to test numbers in JavaScript. But the methods you’ve learned can be used to test other data types such as Array, Object, String, and so on. In addition, although QUnit is useful for testing any JavaScript code, this app is still about jQuery. Therefore, let’s see some examples using all the methods described so far applied to code written using jQuery methods and utility functions:
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');
As you can see, testing different data types is really no different than testing Numbers. Let’s now move on to the other assertion methods.
The other assertion methods
Other assertion methods provided by QUnit are similar in scope and the parameters they accept; therefore we decided to compact them into table 14.1.
Table 14.1. An overview of other assertion methods provided by QUnit
Method | Description |
---|---|
deepEqual(value, expected[, message]) | A recursive, strict comparison that works on all JavaScript types. The assertion passes if value and expected are identical in terms of properties and values and value and expected also have the same prototype. |
notDeepEqual(value, expected[, message]) | Same as deepEqual() but tests for inequality of at least one property or value. |
propEqual(value, expected[, message]) | A strict comparison of the properties and values of an object. The assertion passes if all the properties and the values are equal in a strict comparison. |
notPropEqual(value, expected[, message]) | Same as propEqual() but tests for inequality of at least one property or value. |
ok(value[, message]) | An assertion that passes if the first argument is truthy. |
To see these new methods in action, let’s build a function that tests if a number is even:
function isEven(number) {
return number % 2 === 0;
}
To test the isEven() function you may write
assert.strictEqual(isEven(4), true, '4 is an even number');
But by using the ok() method you can simplify the assertion:
assert.ok(isEven(4), '4 is an even number');
Much better, isn’t it?
The difference between deepEqual() and propEqual() is subtle but important. To understand it, let’s define an object literal called human with a property named fullName that’s initialized to null. In addition, let’s define a function called Person that has to be used as a constructor that accepts as its only parameter a string and defines a property on the created object named fullName. The code to create the function and the object literal is the following:
function Person(fullName) {
this.fullName = fullName;
}
var human = {
fullName: null
};
Now you can instantiate an object of type Person setting "John Doe" as the value of fullName and also set the fullName property of the human object literal. Then you can test for their equality using deepEqual() and propEqual() to highlight their difference. The relevant code is shown here, but it’s also available in the file lesson-14/test.3.html and as a JS Bin:
QUnit.test('Testing propEqual() and deepEqual()', function(assert) {
assert.expect(2);
var person = new Person('John Doe');
human.fullName = 'John Doe';
assert.propEqual(person, human, 'Passes. Same properties and values');
assert.deepEqual(person, human, 'Fails. Same properties and values, but different prototype');
});
If you run this test, you’ll see that the first assertion passes but the second fails. The reason is that the objects person and human have the same properties and values but different prototypes (person has Person as its prototype whereas human has Object as its prototype). This condition is sufficient to pass an assertion using propEqual() but not using deepEqual().
There’s one last assertion method to discuss.
Leave a Reply