Voice of A Developer: JavaScript Unit Test - Part 34

Introduction

 
Before moving further, let us look at the previous articles of the series

JavaScript

 
JavaScript is a language of the Web. This series of articles will talk about my observations learned during my decade of software development experience with JavaScript.
 

Unit tests

 
Unit testing is a software development process in which the smallest parts of the Application, called units, are tested. It can be done manually orthe process could be automated. Unit Testing is a level of software testing where the individual units/ components of the software are tested. The purpose is to validate that each unit of the software performs as designed.
 

Advantages of Unit tests

 
I see a lot of advantages in Unit tests, I have listed all of them as per my experience,
  • It allows you to make big changes to the code quickly.
  • Improves the design of the code, especially with Test-Driven Development.
  • It makes it easier to change and refactor code.
  • Saves your development time.
Unit tests and TDD go hand-in-hand. The concept of TDD is to first write a failing test, then we write enough code to pass the test and refactor the code. Generally, as a developer, we write fast code that works goodwell, but we don’t think to write Unit tests.
 
 
Unit tests are the safety nets and test whether the code is working or not by just running it. 
 
A list of all the unit test frameworks is available here.
 
Few popular frameworks are:
  • Jasmine
  • Mocha
  • Chai
Other concepts
 

Test runner

 
A CLI based tool requires you to run your tests. As developers, we shall love command-line interface and integrate our scripts with it. In an automation, it is of great help and we can integrate the test runner tool with the various environments too. There are many test runner software available. For e.g. Karma, Grunt, Gulp, Nrunner.
 

Assertion

 
It means to validate the condition or the output. We can determine the output; whether a test makes your code fail or pass depends on the assert condition. Different test suites/automation tools syntax can vary but the purpose is the validation, e.g. Assert.IsTrue (true);
 

Pre-requisites

 
You need to install NodeJS to enable the unit tests in JavaScript. You can refer to the article given below, by clicking it.
Let us do Unit testing now. To do that, we will install some node packages, i.e, Jasmine and Karma.
 
There are two ways to install things in NodeJS
  • Global
     
    It installs the node modules in the global space. Hence, you do not need to install it every time for different projects. This is done using –g parameter; while installing. If you are creating your Application to test whether  it's fine or not, you should have in dev dependencies, which is the next option.
     
    [Note for this article, I’ll show –g option for the installation]
     
  • Save local
     
    It installs the node modules in the project directory. Hence, it is a part of the developer dependencies in Package.json [configuration file of NodeJS dependencies] project. If you’re in a hurry to create package.json; then there are various ways you can download a sample using curl command.
     
    Sample package.json
     
    curl -O
     
     
     
  • Jasmine
     
    Jasmine is a test-driven development framework to test JavaScript code. For more details, you can see here.
     
    Now, we will install Jasmine framework, using the command shown below,
     
    npm install –g jasmine
     
     
  • Karma 
     
    Karma is a spectacular test runner for JavaScript. It allows you to execute JavaScript code in the multiple real Browsers. I am emphasizing real Browsers, because it does not run Fake/stubs, but executes tests on the real Browsers. For more details, you can find which Browser, it supports.

Installing Karma and plugins

 
Karma install: fire below command to install karma,
 
npm install –g karma
 

Karma-Jasmine

 
Karma runner supports many different test frameworks like Jasmine, Chai & Mocha etc. We will install karma-jasmine module,
 
npm install -g karma-jasmine
 

Chrome launcher

 
Although we can leverage any supported Browser by Karma,  I will show the tests via most popular Browser Chrome. Hence, install Chrome-launcher,
 
npm install –g karma-chrome-launcher
 

Karma CLI

 
It is a nice interface; from command line to leverage Karma, install,
 
npm install –g karma-cli
 
Write Unit Test Program
  • Create a directory, md testJS
     
     
  • Create tests folder and underneath unitTests.js,
     
     
  • Open file unitTests.js in your favorite editor and paste the code, shown below:
     
    1. describe("UnitTests"function()    
    2. {    
    3.     it("First Unit test"function()     
    4.      {    
    5.         expect(2).toEqual(2);    
    6.     });    
    7. });   
     
    Let us dive deep into the various components of this.
     
    describe
     
    A test suite begins with describing what accepts the title of the suite and a function. This function is going to be tested.
     
    it
     
    Specs are defined, using it. You can write any number of test specifications. A test can be true or false and it depends upon the condition.
     
    expect 
     
    It takes a value and matches against the expected value.
     
  • Configure the test runner
     
    To create this file, quickly download sample karma.conf.js from the location, given below:
     
    curl -O 
     
    Review karma.conf.js for now, we’ll modify it later.
     
    1. module.exports = function(config)     
    2. {    
    3.     config.set(    
    4.       {    
    5.         basePath: '',    
    6.         frameworks: ['jasmine'],    
    7.         files: [    
    8.             'build/js/**/*.js',    
    9.             'build/tests/**/test_*.js'    
    10.         ],    
    11.         exclude: [],    
    12.         preprocessors: {},    
    13.         reporters: ['dots'],    
    14.         port: 9876,    
    15.         colors: true,    
    16.         logLevel: config.LOG_INFO,    
    17.         autoWatch: true,    
    18.         browsers: ['PhantomJS'],    
    19.         singleRun: true    
    20.     });    
    21. };   
       
  • Create the folder app and add code file unit.js. The folder structure may look like,
     
     
  • Modify some key-value pairs, according to your code:
     
    1. browsers: ['Chrome'],     
    2. files: [    
    3. 'app/*.js',    
    4. 'tests/*.js'    
    5. ],   
       
  • Run the basic test using karma. Start and it will also open the Chrome Browser and run the test in unitTest.js,
     
     
    Launch Chrome too.
     
     
    Info
     
    You may get an error that Chrome is not properly configured, so please update the path accordingly,
     
    On the command prompt, you could see - it runs your test and print,
     
    Executed 0 of 1 SUCCESS
    Executed 1 of 1 SUCCESS
     
     
    This happens because our expect statement results in true.

TDD principles

 
I am sure that you are familiar with TDD. In TDD, we promote first to write a test and then code. The above example was to quickly demonstrate you passing the test. Now, we will ensure the principles of TDD.
  • First write the fail test (RED)
     
  • Write the minimum code so the test can pass (GREEN)
     
  • Improve the code (Refactor)
     
  • Revisit unitTest.js and we want to create a global library, where we can perform simple mathematical operations like sum, product. I assumed the global object and two functions with it:
     
    1. describe("UnitTests"function()     
    2.          {    
    3.     var g = global;    
    4.     it("Sum test"function()     
    5.        {    
    6.         expect(g.sum(2, 3)).toEqual(5);    
    7.     });    
    8.     it("Product test"function()     
    9.        {    
    10.         expect(g.product(2, 3)).toEqual(6);    
    11.     });    
    12. });   
       
    Note
     
    Follow TDD principle, I will first fail my tests.
     
     
    At the terminal, it says, “global is not defined”, that means my test is in RED. 
     
  • Next step to writing minimum code is to turn it into GREEN,
     
    Update the code in unit.js, as shown below:
     
    1. var global =     
    2.     {    
    3.     sum: function(a, b)     
    4.     {    
    5.         return a + b;    
    6.     },    
    7.     product: function(a, b)    
    8.       {    
    9.         return a * b;    
    10.     }    
    11. };   
       
  • Again, run karma start command,
     
     
    Nice, we can see both tests, that passed.
     
  • Refactor code by using the “use strict” and replacing var with let keyword inside test will ensure:
     
I committed this code at GitHub and from here you can download or clone it.
 

Summary

 
We can go more in-depth if we want by understanding Karma configuration, Jasmine, and other frameworks. I believe this article must have given you the context of Unit test in JavaScript. Please share your feedback/comments.