Voice of A Developer: JavaScript Unit Test - Part 34

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

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,

  • Allows you to make big changes to the code quickly.
  • Improves the design of the code, especially with Test-Driven Development.
  • 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.


Source http://www.juancarbonel.com/

Unit tests are the safety nets and test whether the code is working or not by just running it.

List of all the unit test frameworks are 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 softwares 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 Chrome Browser and run 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 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 into true.

TDD principles

I am sure that you are familiar with TDD. In TDD, we promote first to write test and then code. 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 mathemetical 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 terminal, it says, “global is not defined”, that means my test is in RED.

  • Next step to write 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 our 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 about Unit test in JavaScript. Please share your feedback / comments.