Javascript - Qunit Test Framework

> (World Wide) Web - (W3|WWW) > Javascript (Js|ECMAScript) > Javascript - Test

1 - About

Qunit is a unit test framework for Javascript.

Advertising

3 - 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.

4 - Testing

4.1 - Function without the DOM

Extracted from the intro page

  • The function to test
prettyDate.js
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)

Advertising

4.2 - The DOM

Extracted from the intro page

  • The function to test
prettyDate.js
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)

5 - Example

5.1 - Bootstrap

From Tests Bootstrap, each plugin has a file dedicated to its tests in unit/<plugin-name>.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.
Advertising

6 - Documentation / Reference

web/javascript/test/qunit.txt · Last modified: 2019/02/16 17:40 by gerardnico