About
Qunit is a unit test framework for Javascript.
Articles Related
Structure
Qunit consists of:
- qunit.js, the test runner and testing framework,
- qunit.css, which styles the test suite page to display test results
- the mandatory <div id="qunit-fixture"> element in the <body> to provides the fixture for tests
Calling QUnit.test() just adds:
- the test to a queue, and its execution is deferred and controlled by the test runner.
- to keep the Tests Atomic.
Testing
Function without the DOM
Extracted from the intro page
- The function to test
function prettyDate(now, time){
var date = new Date(time || ""),
diff = (((new Date(now)).getTime() - date.getTime()) / 1000),
day_diff = Math.floor(diff / 86400);
if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
return;
return day_diff == 0 && (
diff < 60 && "just now" ||
diff < 120 && "1 minute ago" ||
diff < 3600 && Math.floor( diff / 60 ) +
" minutes ago" ||
diff < 7200 && "1 hour ago" ||
diff < 86400 && Math.floor( diff / 3600 ) +
" hours ago") ||
day_diff == 1 && "Yesterday" ||
day_diff < 7 && day_diff + " days ago" ||
day_diff < 31 && Math.ceil( day_diff / 7 ) +
" weeks ago";
}
- The tests
QUnit.test("prettydate basics", function( assert ) {
function date(then, expected) {
assert.equal(prettyDate("2008/01/28 22:25:00", then), expected);
}
date("2008/01/28 22:24:30", "just now");
date("2008/01/28 22:23:30", "1 minute ago");
date("2008/01/28 21:23:30", "1 hour ago");
date("2008/01/27 22:23:30", "Yesterday");
date("2008/01/26 22:23:30", "3 days ago");
date("2007/01/26 22:23:30", undefined);
});
- The HTML
<div id="qunit"></div>
- The results: (Because the test contains a failing assertion, QUnit doesn’t collapse the results for that test)
The DOM
Extracted from the intro page
- The function to test
var prettyDate = {
format: function(now, time){
var date = new Date(time || ""),
diff = (((new Date(now)).getTime() - date.getTime()) / 1000),
day_diff = Math.floor(diff / 86400);
if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
return;
return day_diff === 0 && (
diff < 60 && "just now" ||
diff < 120 && "1 minute ago" ||
diff < 3600 && Math.floor( diff / 60 ) +
" minutes ago" ||
diff < 7200 && "1 hour ago" ||
diff < 86400 && Math.floor( diff / 3600 ) +
" hours ago") ||
day_diff === 1 && "Yesterday" ||
day_diff < 7 && day_diff + " days ago" ||
day_diff < 31 && Math.ceil( day_diff / 7 ) +
" weeks ago";
},
// The only javascript function with a DOM function (getElements)
update: function(now) {
var links = document.getElementsByTagName("a");
for ( var i = 0; i < links.length; i++ ) {
if ( links[i].title ) {
var date = prettyDate.format(now, links[i].title);
if ( date ) {
links[i].innerHTML = date;
}
}
}
}
};
- The tests
function domtest(name, now, first, second) {
QUnit.test(name, function( assert ) {
var links = document.getElementById("qunit-fixture")
.getElementsByTagName("a");
assert.equal(links[0].innerHTML, "January 28th, 2008");
assert.equal(links[2].innerHTML, "January 27th, 2008");
prettyDate.update(now);
assert.equal(links[0].innerHTML, first);
assert.equal(links[2].innerHTML, second);
});
}
domtest("prettyDate.update", "2008-01-28T22:25:00Z", "2 hours ago", "Yesterday");
domtest("prettyDate.update, one day later", "2008/01/29 22:25:00", "Yesterday", "2 days ago");
- The qunit div element where to print the result
<div id="qunit"></div>
- The #qunit-fixture element where the HTML element to test must be given. Why ? Because it is automatically reset after each test. The DOM then stay unchanged between test (There will be then no side effect where the test are affecting each other)
<div id="qunit-fixture">
<ul>
<li class="entry">
<p>blah blah blah...</p>
<small class="extra">
Posted <span class="time">
<a href="#2008/01/blah/57/" title="2008-01-28T20:24:17Z"
>January 28th, 2008</a>
</span>
by <span class="author"><a href="#john/">John Resig</a></span>
</small>
</li>
<li class="entry">
<p>blah blah blah...</p>
<small class="extra">
Posted <span class="time">
<a href="#2008/01/blah/57/" title="2008-01-27T22:24:17Z"
>January 27th, 2008</a>
</span>
by <span class="author"><a href="#john/">John Resig</a></span>
</small>
</li>
</ul>
</div>
- The results: (Because the test contains a failing assertion, QUnit doesn’t collapse the results for that test)
Example
Bootstrap
From Tests Bootstrap, each plugin has a file dedicated to its tests in unit/
.js.
* unit/ contains the unit test files for each Bootstrap plugin.
* vendor/ contains third-party testing-related code (QUnit and jQuery).
* visual/ contains “visual” tests which are run interactively in real browsers and require manual verification by humans.
To run the unit test suite:
* via Karma, run grunt test-js.
* via a real web browser, open index.html in the browser.
===== Documentation / Reference =====
* https://api.qunitjs.com/ - API
* http://qunitjs.com/
* qunitjs/qunit (3702) (Used by Bootstrap)