Sibeesh Passion

Writing JavaScript Tests Using Jasmine Framework




  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

In this post we will see how we can write unit test cases in JavaScript. Here we are going to use a framework called Jasmine to write and test our unit test cases. Jasmine is a behavior driven development framework to test our JavaScript codes. The interesting things about Jasmine framework are, it doesn’t even require a DOM, independent on any framework, clean and easy. Here I will show you how we can create and run our JavaScript tests. I am going to use Visual Studio 2015 for the development. I hope you will like this article.

Download source code

  • JavaScript Tests With Jasmine
  • Background

    As a developer, we all writes JavaScript codes for our client side developments. Am I right? It is more important to check whether the codes we have written works well. So for that we developer usually do unit testing, few developers are doing a manual testing to just check whether the functionality is working or not. But most of the MNC’s has set of rules to be followed while developing any functionalities, one of them is writing test cases, once the test cases passes, then only you will be allowed to move your codes to other environments. Here I will show you how we can write client side test cases with the help of a framework called Jasmine.

    Setting up the project

    To get started, please create an empty project in your Visual Studio.

    empty_project

    empty_project

    Now, we will install jQuery, jQueryUI from Nuget package manager.

    nuget_package_manager

    nuget_package_manager

    We are all set to start our coding now.

    Creating page and needed JS file

    Next, we are going to create a page as preceding, with two text boxes and needed references.

    <!DOCTYPE html>
    <html>
    <head>
        <title>Writing JavaScript test cases with Jasmine framework - Sibeesh Passion</title>
    	<meta charset="utf-8" />
        <link href="Content/themes/base/jquery-ui.min.css" rel="stylesheet" />
        <link href="Content/themes/base/base.css" rel="stylesheet" />
        <script src="Scripts/jquery-3.1.1.min.js"></script>
        <script src="Scripts/jquery-ui-1.12.1.min.js"></script>
        <script src="Scripts/Index.js"></script>
    </head>
    <body>
        Start Date: <input type="text" name="name" value="" id="dtStartDate" />
        End Date: <input type="text" name="name" value="" id="dtEndDate" />
    </body>
    </html>
    

    Now we can start writing our JavaScript codes in the file Index.js. We will start with a document ready function as preceding.

    $(function () {
        $("#dtStartDate").datepicker();
        $("#dtEndDate").datepicker();
        $("#dtEndDate").on("change leave", function () {        
        });
    });
    

    Shall we create our validation functions? We will be creating a namespace indexPage and functions. You can see the validations below.

    var indexPage = {};
    indexPage.validationFunctions = (function () {
        return {
            getStartDateSelectedValue: function () {
                return $("#dtStartDate").val();
            },
            getEndDateSelectedValue: function () {
                return $("#dtEndDate").val();
            },
            isNullValue: function (selVal) {
                if (selVal.trim() == "") {
                    return true;
                }
                else {
                    return false;
                }
            },
            isNullValueWithUIElements: function () {
                if (indexPage.validationFunctions.isNullValue(indexPage.validationFunctions.getStartDateSelectedValue())
                && indexPage.validationFunctions.isNullValue(indexPage.validationFunctions.getEndDateSelectedValue())) {
                    alert("The values can't be null!.");
                }
            },
            isEndDateGreaterStart: function () {
                var startDate = new Date(indexPage.validationFunctions.getStartDateSelectedValue());
                var endDate = new Date(indexPage.validationFunctions.getEndDateSelectedValue());
                if (startDate < endDate) {
                    return true;
                }
                else {
                    alert("End date must be greater than start date!.")
                    return false;
                }
            }
        }
    }(jQuery));
    

    Hope you are able t understand the codes written. We are wrote some validations like Null value check, end date greater than start date etc…

    Now please run your application and check whether the validations are working fine.

    null_validation_check

    null_validation_check

    date_validation_check

    date_validation_check

    Now, here comes the real part.

    Setting up Jasmine Framework

    To set Jasmine, we will add a new project to our solution.

    add_new_project

    add_new_project

    Now install Jasmine from Nuget Package manager.

    jasmine_nuget_package

    jasmine_nuget_package

    Once you are done, the required files would be added to your project. We will be discussing about Jasmine once everything is set. So no worries.

    Now please add a new HTML file on your Jasmine project, this is the page where we can see the test cases in actions, and add all the references as follows.

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title>Jasmine Spec Runner - Sibeesh Passion</title>
        <link href="content/jasmine/jasmine.css" rel="stylesheet" />
        <script src="http://localhost:12387/Scripts/jquery-3.1.1.min.js"></script>
        <script src="http://localhost:12387/Scripts/jquery-ui-1.12.1.min.js"></script>
        <script src="scripts/jasmine/jasmine.js"></script>
        <script src="scripts/jasmine/jasmine-html.js"></script>
        <script src="scripts/jasmine/console.js"></script>
        <script src="scripts/jasmine/boot.js"></script>
        <script src="scripts/indextests.js"></script>
        <script src="http://localhost:12387/Scripts/Index.js"></script>
    </head>
    <body>
    
    </body>
    </html>
    

    Please do not forget to include the js files where we actually written the validations, jquery, jqueryui (if needed). Here indextests.js is the file where we are going to write the test cases.

    Normally this page is called as Spec Runner, Now you may be thinking what is a Spec? Before going further, there are some terms you must be aware of, there are listed below.

  • Suites
  • A suit is the starting point of a Jasmine test cases, it actually calls the global jasmine function describe. It can have two parameters, a string value which describes the suit, and a function which implements the suit.

  • Spec
  • Like suites, a spec starts with a string which can be the title of the suit and a function where we write the tests. A spec can contain one or more expectation that test the state of our code.

  • Expectation
  • Value of an expectation is either true or false, an expectation starts with the function expect. It takes a value and call the actual one.

    You can always read more here. Now please run your SpecRunner.html page. If everything is fine you can see a page as below.

    jasmine_spec_runner_page

    jasmine_spec_runner_page

    So are you all set? Shall we go and write our test cases? Please go to your IndexTest.js file and create a suit and spec as preceding.

    describe("Includes validations for index page", function () {
        var indexPage;
        beforeEach(function () {
            indexPage = window.indexPage.validationFunctions;
        });
    
        it("Check for null values", function () {
            // We are going to pass "" (null) value to the function
            var retVal = indexPage.isNullValue("");
            expect(retVal).toBeTruthy();
        });
    
    });
    

    Here the expectation is true and we give toBeTruthy(), now lets go and find whether the test is passed or not. Please run the SpecRunner.html page again.

    test_jasmine_specs

    test_jasmine_specs

    Now we will write test case for our function isEndDateGreaterStart, if you have noticed the function isEndDateGreaterStart, you can see that there are dependencies (UI elements). Inside of the function, we are getting the values from the UI elements.

    var startDate = new Date(indexPage.validationFunctions.getStartDateSelectedValue());
    var endDate = new Date(indexPage.validationFunctions.getEndDateSelectedValue());
    

    So in this case, we need to mock this values. It is known as ‘Spy’ in Jasmine. We can use a function called SpyOn for this.

        it("Spy call for datepicker date validation", function () {
            //Start date as 2015-03-25
            spyOn(indexPage, "getStartDateSelectedValue").and.returnValue("2015-03-25");
            //End date as 2015-03-24
            spyOn(indexPage, "getEndDateSelectedValue").and.returnValue("2015-03-24");
            var retVal = indexPage.isEndDateGreaterStart();
            expect(retVal).toBeFalsy();
        });
    

    Here we are giving start date as 2015-03-25 and end date as 2015-03-24 and we know 2015-03-25 < 2015-03-24 is false, so here we are giving expectation as false (toBeFalsy()). Now you are getting an alert as follows right?[caption id="attachment_11912" align="alignnone" width="766"]alert_in_spyon_jasmine alert_in_spyon_jasmine[/caption]

    But in testing framework we don’t need any alerts right? To get rid of this, you must create a spy for window.alert function and add it to the beforeEach so that it can be used for each specs. You can do that as follows.

    window.alert = jasmine.createSpy("alert").and.callFake(function () { });
    

    Once after you add this code, alert message won’t be thrown. Now please add an another spec with true values (Start date – 2015-03-25, End date – 2015-03-26), so that it will return true.

      it("Spy call for datepicker date validation toBeTruthy", function () {
            //Start date as 2015-03-25
            spyOn(indexPage, "getStartDateSelectedValue").and.returnValue("2015-03-25");
            //End date as 2015-03-26
            spyOn(indexPage, "getEndDateSelectedValue").and.returnValue("2015-03-26");
            var retVal = indexPage.isEndDateGreaterStart();
            expect(retVal).toBeTruthy();
        });
    

    Now you can see all of your specs are passed.

    run_all_specs_in_jasmine

    run_all_specs_in_jasmine

    Happy coding!.

    Conclusion

    Did I miss anything that you may think which is needed? Could you find this post as useful? I hope you liked this article. Please share me your valuable suggestions and feedback.

    Your turn. What do you think?

    A blog isn’t a blog without comments, but do try to stay on topic. If you have a question unrelated to this post, you’re better off posting it on C# Corner, Code Project, Stack Overflow, Asp.Net Forum instead of commenting here. Tweet or email me a link to your question there and I’ll definitely try to help if I can.

    Kindest Regards
    Sibeesh Venu

    • Karthik Sachin

      good and Very useful dude.

    Footer With Address And Phones