QUnit’s setup is fairly simple and is easy to use. To get started, I will be using a simple boilerplate webpage. Notice that the two files required for QUnit (qunit-x.js and qunit-x.css) are included in the page source. Additionally, I have some inline JavaScript for which QUnit tests will be written.

home.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Homepage</title>
  <link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.17.1.css">
</head>
<body>
  <div id="qunit"></div>
  <div id="qunit-fixture"></div>
  <script src="//code.jquery.com/qunit/qunit-1.17.1.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <script>
  var app_home = (function() {
    function getData() {
      var obj = {
        user_msg:'Welcome to the homepage',
        page_heading:'Homepage heading'
      };
      return obj;
    }

    return {
      getData:getData
    };
    })();

    // app logic
    jQuery(document).ready(function() {
      app_home.getData();
    });
  </script>
  <script src="tests.js"></script>
</body>
</html>

Within tests.js, I have included two basis JavaScript tests. The first test is to verify that the data within app_home.getData()matches the expectations and the second test verifies the page title. Note that QUnit enables you to group tests into modulesusing QUnit.module().

tests.js

// Homepage
if(typeof app_home !== 'undefined') {
	QUnit.module("home");
	QUnit.test( "homepage data", function( assert ) {
	  var actual_obj = {
				user_msg:app_home.getData().user_msg,
				page_heading:app_home.getData().page_heading
			};
	  var expected_obj = {
				user_msg:'Welcome to the homepage',
				page_heading:'Homepage heading'
			}; 
	  assert.deepEqual( actual_obj, expected_obj, "Homepage data should match expected data");
	});
	QUnit.test( "page title", function( assert ) {
  		assert.equal( document.title, "Homepage", "page title should match expectation" );
	});
}

Opening home.html in a web browser should display the QUnit test results.

qunit-test

As a website or app scales, running these tests manually within a web browser can be time consuming.

Automating JavaScript tests using Grunt and PhantomJS

For the setup, first install nodejs followed by Grunt Cli
sudo apt-get install nodejs
sudo npm install -g grunt-cli

Within the root directory of your project, create a package.jsonfile with the following content.

package.json

{
  "name": "yourProjectName",
  "version": "0.0.1",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-qunit": "~0.5.2"
  }
}

npm-installSubsequently, run npm install. This should install grunt andgrunt-contrib-qunit packages within your project. You can view the contents of these packages within the node_modulesdirectory.

The next step is to create a Gruntfile.js file within the root directory of your project with the following content. Note that Gruntfile allows command line parameters and web page specific settings to be passed to PhantomJS.

I have illustrated a few of these options in the Gruntfile below. For instance, “–cookies-file” property can be used to write cookie data to a text file. Similarly, under page specific settings – options like “resourceTimeout”, “userAgent” etc., can be set.

Gruntfile.js

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    qunit: { 
      options: {
      	'--ignore-ssl-errors':true,
      	'--max-disk-cache-size':100000,
      	'--load-images':false,
      	'--local-to-remote-url-access':true,
      	'--ssl-protocol':'any',
        '--cookies-file':'cookies.txt'
      },
      all: {
      	options: {
      		urls: [
      			'http://test.local/home.html?module=home'
      		],
      		page: {
      			settings: {
      				resourceTimeout:10000,
      				//userAgent:'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3',
      				loadImages:false,
      				localToRemoteUrlAccessEnabled:true,
      			}
      		}
      	}
      }
    }
    
  });  
	grunt.loadNpmTasks('grunt-contrib-qunit');
	grunt.registerTask('default', ['qunit']);
};

Please go through the PhantomJS API for the full list of options.

Specifying the user agent for PhantomJS

Notice that I have commented out the userAgent property in Gruntfile – which is set to iPhone’s useragent. Uncommenting this line allows you to run the same set of JavaScript tests within PhantomJS with the useragent set to iPhone.

grunt-qunit-task-runner

 

Lastly, the grunt command can be run with arguments like --verbose to see additional information and --debug to review each HTTP(S) request in PhantomJS and the sequence of QUnit steps.