07.Unit Testing
Overview
In case logic handles complex processes, if test procedure is implemented in Javascript as well, it would be much helpful for quality assurance.
There are several JavaScript testing tools, such as JSUnit, QUnit, JSSpec etc.
In hifive, due to the following reasons:
- Since asynchronous processing is supported, thorough test can be made possible.
- Simple and easy to use.
- Used by jQuery.
QUnit is selected for testing.
Installing QUnit & Test implementation method
- Download qunit.js and qunit.css.
- Import qunit.js and qunit.css into the page to be tested.
- Write test cases into the HTML file.
- When the HTML file is opened, test process will be executed and result will be displayed.
Basic syntax
The sample code that uses QUnit is shown as below. This sample can be referred from:
http://docs.jquery.com/QUnit#source
<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
<!--Executable standalone QUnit
<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
<script>
// Module independent test
test("a basic test example", function(){
ok(true, "this test is fine");
var value = "hello";
equal("hello", value, "We expect value to be hello");
});
module("Module A"); // Define "Module A"
test("first test within module", function(){ // Test "Module A"
ok(true, "all pass");
});
module("Module B"); // Define "Module B"
test("some other test", function(){ // Test "Module B"
expect(2); // Set expected assertion count to 2
equal(true, false, "failing test"); // Since the test fails under this condition, expected count cannot be satisfied thus expect() will fail
equal(true, true, "passing test");
});
module("Module C");// Define "Module C"
asyncTest("asyncTest", function(){ // Test "Module C"
// Execute a time-consuming process
setTimeout(function(){
// Implementing assertion for time-consuming process
ok(true, "always fine");
start();
}, 100); // After 100 miliseconds, execute a function which is argument 1 of setTimeOut()
});
test("asyncTest by normal test", function(){ // Test "Module C"
stop(1); // Since asynchronous test is executed in test(), set number of semaphores in stop() function (number of times start() is called)
// Execute time-consuming process
setTimeout(function(){
// Implement assertion for time-consuming process
ok(true, "always fine");
start();
}, 200); // After 200 miliseconds, execute a function which is argument 1 of setTimeOut()
});
</script>
</head>
<body>
<!-- Test result displayed here -->
<div id="qunit"></div>
<div id="qunit-fixture">test markup, will be hidden</div>
</body>
</html>
If asynchronous communication is performed
- Test process will be halted in stop() function. Executing start() function in the function that is executed when asynchronous communication result is returned will resume test cycle.
stop(1); // Since start() will be called only once after asynchronous processing completed, set semaphore to 1.
$.getJSON("/someurl", function(result) {// Get JSON result during waiting time (1s)
equal(result.value, "someExpectedValue"); // Compare result
start(); // Test process resumes after assertion is executed.
});
});
- stop() function takes semaphore value as a parameter (unless specifically indicated, the value will be set to 1).
If Timer is set
- The example below implements test using asyncTest() function.
setTimeout(function(){
// Implement assertion for time-consuming process
equal(obj.value, expectValue);
start();
},100 /* Wait 100ms */);
});
});
- The test will end when start() is called. During processing, other test will not be called.
- Refer to: http://d.hatena.ne.jp/Jxck/20100721/1279681676
If Assert is used for manipulating DOM
- The example below shows a simple modification of DOM node element.
var domtest = document.getElementById("dom_test");
equal(domtest.id, "dom_test");
domtest.setAttribute("id", "dom_test2");
notEqual(domtest.id, "dom_test");
equal(domtest.id, "dom_test2");
});
Next Chapter⇒08. Document generation (JSDoc)