Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Hosted-services / ExtJS

Step by Step Guide for Unit Testing ExtJS Application using Jasmine

4.94/5 (3 votes)
3 Oct 2013CPOL5 min read 73.4K   2.1K  
The article is a step by step guide to enable unit testing ExtJS applications using Jasmine.

Introduction

This article is a Step by Step guide on how to do Unit testing of ExtJS application using Jasmine Framework. The MVC approach of ExtJS along with the ‘Behavior Driven Testing’ approach of Jasmine Framework enables independent testing of ExtJS model, store and controller.

Background

ExtJS is a Model-View-Controller (MVC) based Javascript framework used to develop Rich Internet Applications. The architecture of ExtJS enforces keeping the model/view/controller in different files to develop desktop like applications. ExtJS architecture necessitates creation of model, view and controller, preferably as separate files. As per the MVC paradigm:

  • Model represents the state of the Entity
  • View deals with the presentation logic of the entity and
  • Controller mediates between Model and view by handling events occurring on the model/view and updates the model/view in response to events.
The MVC architecture, as detailed above, facilitates writing unit tests for the controller and store. This approach doesn't require to fire events from the View, since all the events occurring on the View are bound to event-handlers which are JavaScript functions in the Controller, so they can be called independently. Similarly the ExtJS store is also independent of the View and can be tested independently.

Jasmine Framework

Jasmine is a JavaScript framework which enables Behavior driven testing of JavaScript code. Jasmine is an independent framework which doesn't depend on any other JavaScript library. It enables the testing of the JavaScript code without any interactions with DOM. Jasmine library can be used to test the functionality of any JavaScript code.

Jasmine can be integrated easily to test ExtJS applications behavior because the controller/store/model of ExtJS are functional pieces of code with minimal reference to the UI. The controller in the ExtJS binds to the different UI events like click, selection etc. and delegates it to the respective event Handlers defined as function in the controller. We can leverage the Jasmine framework to test these event delegates without actually generating the events from the UI.

In this article we will be testing a simple QuestionBank application that enables us to Add/Delete/List multiple-choice questions and answer in the database.

The document contains two zip files, one containing the QuestionBank application (questionbank.zip) without test cases. This zip file can be used as skeleton to write the test cases. The other zip file (questionbank-tests.zip) contains the full codebase along with test cases for quick reference.

For simplicity, the sample application codebase has a sample servlet which uses the array list to return/save the questions.

Let us start exploring the way to create unit-test cases for ExtJS Application.

Components of application

Extract the contents of the WebContent directory in the attached questionbank.zip to your web project called PRJ_DIR. Different components of the application are as follows:

In Nut shell, there are six steps for integration of Jasmine framework with ExtJS for creating the browser based HTML test cases:

  1. Create Test folder structure
  2. Download and set up Jasmine framework
  3. Create test-app.js
  4. Create test cases in Jasmine spec
  5. Create Test HTML files
  6. Execute the test cases

So let us explore these steps one by one.

Step 1: Create Test Folder structure

In order to configure the test cases we need to create folders for Jasmine framework, test cases and configuration file. Create a folder called js in the PRJ_DIR\WebContent directory and create the following folders:

  • js
  • js/jasmine
  • js/test
  • js/spec

The image below shows the final directory structure required. The folder names written in red rectangle are the new folders which are to be created to integrate Jasmine Framework

Image 1

Step 2: Download and Setup Jasmine Framework

In this step we will learn how to setup the Jasmine Framework to enable Unit Testing.

  1. Download the Jasmine Framework bundle "jasmine-standalone-1.3.1.zip" from https://github.com/pivotal/jasmine/downloads
  2. Unzip the jasmine-standalone-1.3.1.zip to any directory of your choice.
  3. Copy the following files to your PRJ_DIR\WebContent\js\jasmine directory
    1. lib/jasmine-1.3.1/jasmine.css to PRJ_DIR/WebContent/js/jasmine/jasmine.css
    2. lib/jasmine-1.3.1/jasmine.js to PRJ_DIR/WebContent/js/jasmine/jasmine.js
    3. lib/jasmine-1.3.1/jasmine-html.js to PRJ_DIR/WebContent/js/jasmine/jasmine-html.js

Step 3: Create test-app.js

We have to create a separate app.js file to enable testing. This file will be created in the PROJECT_DIR\WebContent\js\test directory.

Let us see how to do this:

  1. Create a copy of existing app.js so it looks like:
  2. JavaScript
    Ext.Loader.setConfig ({enabled: true});
    
    // Loading different components like controller, model, view..
    Ext.application ({
    	 controllers:[ 'QuestionController' ],
    	 models: [ 'Question' ],
    	 stores: [ 'QuestionStore' ],
    	 views: [ 'MainPanel' ],
    	 autoCreateViewport: true,
    	 name: 'QAApp'
    });
  3. Set autoCreateViewPort to false so that ExtJS doesn't render any HTML. This is required as we will be testing the controllers/store without initializing View.
  4. JavaScript
    Ext.Loader.setConfig ({enabled: true});
    
    Ext.application ({
         .............
         .............
      // Setting the autoCreateViewPort to initialize the Application without   
      // View being rendered
      autoCreateViewport: false,
      
      name: 'QAApp'
    });
  5. Add the launch function to initialize and execute the Jasmine Test Cases:
  6. JavaScript
    Ext.Loader.setConfig ({enabled: true});
    
    Ext.application ({
         .............
         .............
         autoCreateViewport: false,
         name: 'QAApp',
        
        // using the Launch method of Application object to execute the Jasmine
        //Test Cases
         launch: function () {
    	var jasmineEnv = jasmine.getEnv ();
    	jasmineEnv.updateInterval = 1000;
    	var htmlReporter = new jasmine.HtmlReporter ();
    	jasmineEnv.addReporter (htmlReporter);
    	jasmineEnv.execute ();
         }
    
    });

Step 4: Create Test Cases in Jasmine Spec

Create an empty JavaScript file PROJECT_DIR\WebContent\js\spec\QuizControllerSpec.js. This will act as a placeholder for all the unit test cases.

Start writing the Jasmine Test Cases for example:

describe ("ExtJS Question App Test Suite", function () {
var mainPanel = null;
var questionStore = null;
var questionStore = null;
var storeLength = -1;
var controller = null;
  /* Setup method to be called before each Test case.*/
  beforeEach (function () {
        // Initializing the mainPanel.
       mainPanel = Ext.create ('QAApp.view.MainPanel');
       questionStore = Ext.StoreManager.lookup ('QuestionStore');
       controller = Ext.create ('QAApp.controller.QuestionController');
       storeLength = questionStore.data.items.length;
  }); // before each

  /* Test if View is created Successfully.*/
  it ('Main View is loaded', function () {
        expect (mainPanel != null).toBeTruthy ();
  });

 /* Test if store is loaded successfully.*/ 
  it ('Store shouldn’t be null', function () {
        expect (questionStore != null).toBeTruthy();
   });

  /* Test controller is initialized successfully.*/ 
  it ('Controller shouldn’t be null', function () {
        expect (controller != null).toBeTruthy();
   });

/* Test if Grid in MainPanel is loaded successfully.*/   
  it ('Grid should be loaded', function () {
        expect (Ext.getCmp ("questionGrid") != null).toBeTruthy ();
  });

 /* Test if Grid in MainPanel is loaded successfully.*/   
  it ('Store has items', function () {
  
       expect (questionStore.data.items.length).toBe (storeLength);
  });

 /* Test if new item is added to store.*/   
 it ('New item should be added to store', function () {
        var record = Ext.create ("QAApp.model.Question");
        record.id = 1;
        record.question = 'Questions 3';
        questionStore.add (record);
        expect (questionStore.data.items.length).toBe (storeLength + 1);
        questionStore.removeAt (storeLength);
 });

/* Item should be removed from store via controller.*/   
 it ('Item should be removed from store', function () {
        var record = Ext.create ("QAApp.model.Question");
        record.id = 1;
        record.question = 'Questions 3';
        questionStore.add (record);

        /* Removing item from controller API.*/   
        controller.deleteQuestionFromStore(record);
        questionStore.removeAt (storeLength);
        expect (questionStore.data.items.length).toBe (storeLength);
 });

});

Step 5: Create Test HTML File

This is major file which will integrate Jasmine Unit test cases and code of ExtJS Application. It will include the Jasmine framework, Jasmine test cases, ExtJS test-app.js file. This file will actually execute the test cases.

Please refer the below steps for more details:

  1. Create an empty html file SpecRunner.html with following contents:
  2. XML
    <html>
       <head>
          <title>Test Quiz Application</title>
       </head>
       <body>
       </body>
    </html>
  3. Add Jasmine frameworks CSS and JS files in the test HTML. This is to make SpecRunner.html use Jasmine framework to enable Unit Testing
  4. Add the ExtJS Libraries/CSS in SpecRunner.html. This is required to load the ExtJS codebase in the test file.
  5. Including the Jasmine Test Case File. This will enable the Test cases to be loaded so that Jasmine framework can execute them.
  6. Now Add the app-test.js file to load the ExtJS Application in Test mode.
  7. After executing all the above steps the final SpecRunner.html file will look like:
    XML
    <html>
       <head>
             <title>Test Quiz Application</title>	
            
             // including the Jasmine Files
            <link rel="stylesheet" type="text/css" href="js/jasmine/jasmine.css">
            <script type="text/javascript" src="js/jasmine/jasmine.js"></script>
            <script type="text/javascript" src="js/jasmine/jasmine-html.js"></script>
    
            //including the ExtJS Files
            <script type="text/javascript" src="extjs-4.1.1/ext-all.js"></script>
            <link rel="stylesheet" type="text/css" href="extjs-4.1.1/resources/css/ext-all.css">
     
            // including the Jasmine Test Case file
           <script type="text/javascript" src="js/spec/QuizControllerSpec.js"></script>
    
            // including the test-app.js file to load test cases
           <script type="text/javascript" src="js/test/test-app.js"></script>
       </head>
      <body>
      </body>
    </html>

Step 6: Execute the Test Cases

Executing the Test cases is very easy. Just deploy the application on any Application Server like Tomcat.

Once the application is deployed, then opening the URL http://<servername>:<port>/ExtJSQuizApp/SpecRunner.html will fire the test cases.

The results can be seen as follows:

Image 2

Summary

As we have seen that it’s quite easy to leverage the Jasmine framework to test the ExtJS application. Similarly, we can use Jasmine to test any JavaScript codebase.

Source Code

Attached is the source code of the application with skeleton and test cases.

References

  1. http://www.sencha.com/products/extjs 
  2. http://pivotal.github.io/jasmine/

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)