Thursday, January 29, 2015

Testing your jquery implementation with Jasmine framework

We tend to write lot of javascript /jquery implementations but it is not that easy to test them since not many stable frameworks are available, and not much documentation is provided. Today we will look into one of those framework named Jasmine, and how to write unit tests using it.

1. Jasmine Framework
Jasmine framework supports Behavior Based Development (BDD) . That is in this type of testing, we describe our code and tell the test what it should be doing. Then we expect the code to act in the described way and see the results. Following code segment brings out this style in the most basic manner.

// describe your  implementation objective
describe(' shopping cart', function () {

// what your test should check
it( ' add items to cart' ,function (){

//expect this to happen at the end
   expect(shoppingCart).toEqual(set of items);
});

});

Note that words highlighted are key words.
Above is the basic set of specification you would need to create your unit tests. Section 'describe' is basically similar as to defining a test suite while section 'it' is similar to defining a single test case. You can add multiple sets of 'it' cases inside your 'describe' block. Before we get into more detail with writing tests, we will first look into how to setup jasmine framework.

2. Setting up Jasmine Framework

   2.1 Download jasmine standalone package (I have used jasmine 2.1.3) from https://github.com/jasmine/jasmine/releases and unzip it .
2.1 Copy following file and folders , SpecRunner.html, lib, spec and src.
2.3 Create a new folder (I'll call it shoppingcart) and add those folders to it .


Now you have done the basic setup required. Now you need to add all your .js (source files) under src folder. Next you can create your test specification files (where you will write your test cases) into spec folder. lib folder is where you can add all your dependencies required. By default it will have jasmine. If you are to test jquery related coding, you need to download jasmine-jquery ( https://github.com/velesin/jasmine-jquery) and include that file inside lib folder. SpecRunner.html is the file where you get to define all the source ,specs and libraries that you need to use in your tests. In that file, you can add your links as follows.
    <!-- include library files here... -->

   <script src="lib/jasmine-2.1.3/jasmine.js"></script>
        <script src="lib/jasmine-2.1.3/jasmine-html.js"></script>
        <script src="lib/jasmine-2.1.3/boot.js"></script>
        <script src="lib/jquery.min.js"></script>
         <script src="lib/jasmine-jquery.js"></script>
             
    <!-- include source files here... -->

        <script src="src/addItems.js"></script>
    
      
        <!-- include spec files here... -->

        <script src="spec/shoppingCart_spec.js"></script>

Note that in order for jquery-jasmine to work, you need to include jquery dependency as well, and you need to add it before where you specify jasmine-jquery. Else you will get a jquery undefined error. 
   

Jasmine framework supports lot of matcher keywords that you can use to test your jquery code. You can also write your own custom matchers as well. Refer to jasmine documentation for more information on this.

We will look into few basic unit tests of jquery so you can get an idea on how to start. Following is the addItems. js source file which contains the implementation I need to test.


var itemList = []; 

function addItem ( item) {

itemList.push(item);
}

function removeItem(item)
{
  itemList.splice(item,1);
}

function findItemOnList(item) {
for (var i =0 ;i <itemList.length; i++){
if( item  === itemList[i].item){
return true;
}
else{
return false;
}
}

Now we will look into how to write unit tests for above functionalities.  Note that I have highlighted keywords and matchers in blue. This is how your shoppingCart_spec.js would look like.

describe('Shopping Cart' , function () {

var defaultItem;
var defaultName = "groceries";

beforeEach(function(){

   defaultItem = createNewItem(1,defaultName);
   addItem(defaultItem);
});

afterEach(function() {
        itemList = [];
    });

it('Add item to shopping cart',function () {
var itemName = "stationary";
      var item = createNewItem(2, itemName); 
      addItem(item);

   expect(itemList.length).toEqual(2);

});

it('Remove item from shopping cart' ,function () {
    removeItem(defaultItem);

expect(itemList).toContain(null);
});

it('Search for  valid item on shopping cart' , function () {
    var result = findItemOnList(defaultItem); 
     expect(result).toBe(true);
});

it( 'Search for invalid item on shopping cart', function () {
var itemName = "stationary";
  var newItem = createNewItem(2,itemName);
  var result = findItemOnList(newItem);
expect(result).toBe(false);

});
});

Now I add additional createNewItem method into my SpecRunner.html as below .

 <script type="text/javascript">

function createNewItem(id, name) {
 var item = $(<div>);

item.attr({
id:id,
name:name
};

return item; 
}

</script>

Note that I have used different matchers under expect sections so you can get an idea on how they can be used. beforeEach and afterEach code blocks can contain any resetting or functionality that can happen before and after every individual 'it ' block. Note how i have used the functions and variables in addItem.js source code.  Finally once your test cases are completed, you can launch SpecRunner.html in your favourite browser and run the specifications.  This is a very basic start up guide for you. Jasmine framework supports lots of functionalities such as testing ajax calls , triggering mouse events, testing css properties.




No comments:

Post a Comment