Sunday, January 23, 2011

Qunit- Unit Testing JQuery and JavaScript


QUnit is a powerful JavaScript unit testing framework that helps you to debug code

HOW TO SET-UP THE UNIT TESTS

So what do you need to get started with jQuery Unit Testing? To begin with download both of the following files, Qunit.js, & Qunit.css, and include them in the head of your HTML document along with the latest version of jQuery. Then add the following HTML to the body of your document so that Qunit can render the test results properly:
2
3
4
5
<h1 id="qunit-header">QUnit example</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
As you can see, getting set up with a basic testing environment is easy and pretty simple. With this set-up you can then include your own Qunit tests either in a SCRIPT tag or in your own JavaScript external include.

WRITING YOUR OWN UNIT TESTS

So now you’re ready to start writing your own tests, lets keep it clean and simple. The unit testing API is split into 3 sections:
  1. Setup – The basics for defining tests, grouping them and getting them started.
  2. Assertions – The Yay and the Nay of whether conditions have the met with boolean tests, comparison tests and recoursive comparison assertions for arrays, objects, etc.
  3. Asynchronous Testing – Functions to stop and start the test runner
Read More..
Putting this together – not that we have looked in depth thus far – a very basic unit test would look as follows:
2
3
4
5
6
7
8
module("Initial Test Module");
 
test("Test with multiple assertions", function() {
  expect(2);
  equals( true, false, "failing test" );
  equals( true, true, "passing test" );
});
Deconstructing the above test. “Module” provides a means by which to delineate individuals sets of unit tests. The “test” function with title and callback function params includes 2 further functions: “expect” and “equals”. The former sets the expectation for the number of assertions that have been defined and follow, whilst the latter obviously does the grunt work and returns the results. In defining an assertion you need to provide 3 things:
  1. The expected result.
  2. The result.
  3. An error message
As you can see writing even the most basic tests is super simple and pretty much a no-brainer. Adding complexity to the mix, with more test modules, multiple test and assertions interlinked and daisy chained together makes for a powerful brew.
Some more Examples :


function isEven(val) {
return val % 2 === 0;
}

test('isEven()', function() {
ok(isEven(0), 'Zero is an even number');
ok(isEven(2), 'So is two');
ok(isEven(-4), 'So is negative four');
ok(!isEven(1), 'One is not an even number');
ok(!isEven(-7), 'Neither does negative seven');
// Fails
ok(isEven(3), 'Three is an even number');
})

Identical Assertions
Identical assertion, same(), expects the same parameters as equals(), but it’s a deep recursive comparison assertion that works not only on primitive types, but also arrays and objects. Assertions, in the previous example, will all pass if you change them to identical assertions:
  1. test('test'function() {  
  2.     same( {}, {}, 'passes, objects have the same content');  
  3.     same( {a: 1}, {a: 1} , 'passes');  
  4.     same( [], [], 'passes, arrays have the same content');  
  5.     same( [1], [1], 'passes');  
  6. })  
Notice that same() uses ‘===’ to do comparison when possible, so it’ll come in handy when comparing special values:
  1. test('test'function() {  
  2.     equals( 0, false'true');  
  3.     same( 0, false'false');  
  4.     equals( null, undefined, 'true');  
  5.     same( null, undefined, 'false');  
  6. }) 

WRAPPING THINGS UP
To my mind there is little point in re-inventing the wheel, especially when so many good test examples exist, and which you can draw on for ideas in your own testing, but I thought it might be worth highlighting various points that can add flavour to your unit tests:
  • “Module” provides lifecycle hooks for running code on setup and teardown of each test and you can just as easily bind tests to functions and events via jQuery also. Good examples exist in the actual jQuery core tests for the AJAX calls (core.js, ajax.js, etcetera).
  • Daising chaining your assertions together makes for useful testing when wishing to assert that different types of scenarios, for example when making invalid requests to an AJAX web service with illegal characters, insufficient parameters, unauthorised params etc will fail properly, and thus pass your tests accordingly.  Definitely worth using when testing forms and data entry.
  • Manipulate the DOM and everything else has much as possible during the course of your tests.  Alter the underlying code and test for the results as you go.  You shouldn’t be afraid to try and break things and test against them. It’s very easy to get into the developer mindset where you know how they should work, and you are can make them work perfectly all the time.

No comments:

Post a Comment

subversion video