Wednesday, 16 May 2012

SharePoint JavaScript Unit Testing with Jasmine


So recently while working on some code, I realized that I have not yet ventured into the field of Unit Tests and TDD. I had read about it plenty but never had got an opportunity to work on it. Test Driven Development (TDD) consists of writing the test cases before you write your code. It mainly consist of 3 factors: Red, Green and Refactor. Red indicates writing of a test case which will always fail, mainly because of the fact that the functionality for passing the test has not yet been written. Next, Green indicates the creation of the functionality which will pass the test. And finally, Refactor indicates the re-modelling of your code to make it more efficient and performance friendly.

Since I am writing a lot of JavaScript these days, I decided to go forward and introduce TDD into my JavaScript Projects. When I was looking for more information on JavaScript Unit Testing, the one framework which immediately grabbed my attention was Jasmine. It came with a terse and easy syntax and it clearly outmatched the other frameworks in functionality and ease of use. More over, it could be used completely client side in the browser as a standalone framework. So I decided to go forward and implement it. (You can try out Jasmine here without installing anything).

Now being a SharePoint developer, things are not always as easy as they seem. You will find a lot of tutorials on the web integrating Jasmine with various technologies but almost none when SharePoint comes into the picture. So like most of the times, it was on me to figure out how to integrate the Jasmine Unit Testing Framework with SharePoint JavaScript and create successful Unit Tests with it.

As I mentioned before, the good thing about Jasmine is that you can use it as standalone framework without making much configuration settings. It completely runs in the browser and presents a very rich and informative UI when it comes to indicating whether a test has passed or failed.

Integrating it with SharePoint:

Following is my SharePoint project structure. I have included all the files for the tests in the "Tests" module (As highlighted below)


Now, the Jasmine framework requires some basic JS and html files to run the tests and display the results. 

  1.  The jasmine.js file does all the heavy lifting.It contains the code of the testing framework.
  2.  The jasmine-html.js, jasmine.css and the SpecRunner.aspx page all work in the presentation layer and provide a nice rich UI to display the result of the tests. 
  3.  The maiFileSpec.js is the specrunner which will contain and run all the tests for the JavaScript functions.
  4.  The mainFile.js is a regular old JavaScript file which will  contain all of our code which has to be tested. This does not have to be a single file you can test functions in multiple JS files also.
Now lets get into some code. Here is the code for my mainFile.js which has the functions which we will be testing with the Jasmine Framework:

This file contains 3 functions. MakeInt converts a value to a integer with radix 10. Divide returns the first number divided by the second number. It throws an error is the second number is 0. CreateJQObject creates and returns a jQuery object with the the specified HTML tag, is and class.

Now lets have a loot at the mainFileSpec.js file, which we will be using to test the functions defined in the previous file.



Now lets aggregate all this code in one aspx page so that we can carry out the tests. Here is how my SpecRunner.aspx looks:



Now once we deploy this project to the SharePoint site, all we have to do is navigate to the SpecRunner.aspx page to where it is deployed and the tests will be automatically run:


Now lets, change some code so that the tests will fails and we will get to see how jasmine displays the failed tests UI. I am changing the following code in the Test for the CreateJQObject function:
expect(jqObject.length).toEqual(0);
This test will now fail because the length of the jQuery object will be 1 and the test expects it to be 0.

Also, lets change one more thing. The error thrown by the Divide function:
 expect(testErr).toThrow(new Error("Result will be Infinity because divisor is 0"));
This test will also fail because the test is expecting one error but the code will throw another kind of error.

Lets runs the tests and find out. After running the test, we are presented with the following UI:



So as you can see, if the test fails we are presented with the functions which are failing, their expected and actual values and the execution queue which caused the error.

So in conclusion, TDD can be very easily achieved in JavaScript with help of the Jasmine JavaScript Framework. Moreover, we can utilize the framework inside SharePoint as well!

Have fun coding!