Jasmine Unit Testing Tutorial: A Comprehensive Guide

  • Learning Hub
  • Jasmine Unit Testing Tutorial: A Comprehensive Guide

OVERVIEW

In software engineering, collaboration is key. Therefore, it is important to integrate collaboration into all aspects of the engineering processes during development.

In light of it, Behavior-Driven Development (BDD) is a process that encourages collaboration among developers, quality assurance experts, and customer representatives in a software project.

To achieve effective collaboration amongst development teams, BDD combines general techniques and principles of Test-Driven Development (TDD) to provide collaborative tools for software teams.

Therefore, since BDD is an extension of TDD, it requires tools that integrate the principles of BDD and the extensions of Test-Driven Development. That's exactly where Jasmine – the open-source JavaScript-based BDD testing framework comes in.

In this Jasmine unit testing tutorial, we will explain the basics of testing with Jasmine and discuss different Jasmine and testing concepts such as test suites, spies, specifications, expectations, matchers, etc. Additionally, you'll learn from a practical example of writing unit tests with Jasmine to check bugs in your code.

So, let’s get started!

What is Jasmine framework?

Jasmine is a popular open-source JavaScript-based testing framework for unit testing JavaScript applications. It follows a BDD procedure to ensure that each line of JavaScript code is appropriately tested.

In addition, Jasmine has over 15.5k stars and is used by over 2.6m projects on GitHub. It has a strong community of developers, and great documentation is available if you get stuck.

In the next section of this Jasmine unit testing tutorial, we will explore what Jasmine is used for and what type of project you can integrate with Jasmine. You can learn more about the Jasmine framework through this blog on Jest vs Mocha vs Jasmine.

LambdaTest

What is the Jasmine framework used for

With over 2.6m projects using Jasmine as their collaborative testing framework. It is clear that software testing remains vital, and Jasmine has gained industry recognition.

In 2000, JsUnit was the available automation testing framework for JavaScript applications, and later, this framework got upgraded to Jasmine.

Angular developers favor Jasmine because it is included natively in Angular projects. In addition, the key value proposition of Jasmine is that it's easy to set up and write tests.

In the next section of this Jasmine unit testing tutorial, we will elucidate how to use Jasmine. We will discuss the different ways to install, configure, and start using Jasmine to perform your automated testing and BDD.

How to use Jasmine

Now that the fundamentals are out let's get our hands dirty. Let's see how to go from zero to hero with Jasmine unit testing.

There are different ways to install, configure and start using Jasmine in your projects. Let's explore these different ways.

  • Using Standalone Jasmine
  • Using Jasmine as a Library
  • Using Jasmine via CLI
  • Jasmine for browsers

Jasmine is available in different programming languages and can be used to test different microservices written in different languages.

However, this Jasmine unit testing tutorial will focus on JavaScript and explore how to perform Selenium automation testing with Jasmine framework.

Using Standalone Jasmine

The standalone distribution allows you to run your specs in a web browser. You can start by downloading the latest version from the release page and extracting the file to your preferred location inside the project you want to test.

The extracted file will contain many default files, folders, and sample test cases to get you started:

  • /src: This folder contains the source files you want to test. You can delete this folder if your project's folder is set up differently
  • /lib: This folder contains the core Jasmine files and should not be deleted
  • /spec: It contains the tests you will write
  • SpecRunnner.html: This file is used as a test runner. You run your specs by launching this file in your browser

The code snippet below is the default content of the SpecRunner.html file:.

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>Jasmine Spec Runner v3.2.1</title>
 
 <link rel="shortcut icon" type="image/png" href="lib/jasmine-3.2.1/jasmine_favicon.png">
 <link rel="stylesheet" href="lib/jasmine-3.2.1/jasmine.css">
 
 <script src="lib/jasmine-3.2.1/jasmine.js"></script>
 <script src="lib/jasmine-3.2.1/jasmine-html.js"></script>
 <script src="lib/jasmine-3.2.1/boot.js"></script>
 
 <!-- include source files here... -->
 <script src="src/Player.js"></script>
 <script src="src/Song.js"></script>
 
 <!-- include spec files here... -->
 <script src="spec/SpecHelper.js"></script>
 <script src="spec/PlayerSpec.js"></script>
 
</head>
<body>
</body>
</html>

GitHub

Most importantly, you can change the source location of the /src and /spec folders to locate your actual source and test files.

Using Jasmine as a Library

You can use Jasmine as a library in your project. The `jasmine` module is a command line interface and code for running Jasmine specs with Node.js.

  • You can install Jasmine using npm in your project
    npm install –Dev jasmine
    Here is the screenshot of the outputnpm install –Dev jasmine
  • Next, you can run the `init` command to initialize and set up Jasmine in your local project.
    npx jasmine initnpx jasmine init
  • Lastly, you can load it into your project with your configurations:

    var Jasmine = require('jasmine');
    var jasmine = new Jasmine();
     
    jasmine.loadConfigFile('spec/support/jasmine.json');
     
    jasmine.execute();
    

The configuration can be loaded from any location. Also, you can create a custom configuration to fix your project requirements.

Using Jasmine via CLI

  • To use this approach, we will install Jasmine globally into our machine, allowing us to use Jasmine across different projects by installing again.
    npm install -g jasmine
    Here is the screenshot of the outputnpm install -g jasmine
  • In some cases, you may need to run the command with sudo when installing npm packages.
  • Now, we can create a folder for your project and navigate inside it:
    mkdir my-jasmine-project & cd ./my-jasmine-project
    mkdir my-jasmine-project & cd ./my-jasmine-project
  • Next, run the initialized command to setup Jasmine in your new project:
    npx jasmine init
    npx jasmine init
  • The command will create the jasmine folder and some default configurations. The most important file is the `jasmine.json` file, which contains the configurations. You can customize the file to fit your project structures

    {
     "spec_dir": "spec",
     "spec_files": [
       "**/*[sS]pec.?(m)js"
     ],
     "helpers": [
       "helpers/**/*.?(m)js"
     ],
     "env": {
       "stopSpecOnExpectationFailure": false,
       "random": true
     }
    }
    

Below is the list of some of the important configurations inside the `jasmine.json` configuration file.

  • spec_dir: It specifies where Jasmine looks for test files
  • spec_files: It specifies the patterns of test files. All the javascript test files will default end with `.spec.js` or contain the word `spec.`
  • helpers: The helper folder is where Jasmine looks for helper files. These files are executed before specs and can be used to define custom matchers
  • stopSpecOnExpectionFailure: This tells Jasmine to stop execution if any test fails. This works if the configuration is set to true
  • random: Jasmine will pseudo-randomly run the test cases when set to true

You can find more CLI options from the official documentation when running the Jasmine commands. Below are some of the useful CLI options:

  • –-config: The config option is used to specify the relative path to where the configuration file is located.
  • –-no-color: This option turns off colors in spec output.
  • –-filter: The filter option is used to run only the specs that match a given string.

Set Jasmine as your test script in your package.json file:

"scripts": { "test": "jasmine" }

Jasmine for browsers

You can also use Jasmine in the browser, if you're working on the frontend, you can install Jasmine into your project and test out your frontend projects.

  • Run the following command to add Jasmine to your package.json:
    npm install --save-dev jasmine-browser-runner jasmine-core
    Here is the screenshot of the outputnpm install --save-dev jasmine-browser-runner jasmine-core
  • Initialize Jasmine in your project:
    npx jasmine-browser-runner initnpx jasmine-browser-runner init
  • Set Jasmine as your test script in your package.json file:
    "scripts": { "test": "jasmine" }
    Moreover, choosing a specific approach depends on your project requirements and use cases. Is any approach still using Jasmine as your BDD?
  • Finally, to run your test, use the NPM command below:
    npm test

In this section of this Jasmine unit testing tutorial, we explore different methods to set up Jasmine for your testing needs. In the next section of this Jasmine unit testing tutorial, we will understand the Jasmine testing framework deeper and explore the general keywords used in Jasmine and software testing.

Understanding Jasmine testing framework

This section will explore the basic elements of Jasmine testing, such as suites, specs, expectations, matchers, spies, etc.

We will start by creating a demo project that will enable us to practically learn and understand the different elements used in Jasmine testing.

  • Create a project folder in your desired location and run the following command to initialize a new project's package.json file.
    npm init -y
  • Next, create an `helpers.js` file and add the following code:

    function fibonacci(num, memo) {
     memo = memo || {};
     
     if (memo[num]) return memo[num];
     if (num <= 1) return 1;
     
     return (memo[num] = fibonacci(num - 1, memo) + fibonacci(num - 2, memo));
    }
     
    module.exports = {
     fibonacci: fibonacci,
    }
    

The snippet above is a simple Fibonacci series computation. We will use it to understand the different elements of Jasmine testing.

Suites

A suite is a group of specs or test cases. It's used to test a group of features or behavior of the JavaScript code. It's usually encapsulated by an object/class or a function. You can define a suite of test cases using the `describe` block.

The `describe` block takes two required parameters – a string for the suite name and a function that implements the actual code of the test suite.

Let's explore an example of our first Jasmine test suite:

describe('Test Helpers', function () {
 /**
  * Add all your related test cases here
  *
  */
});

With the `describe` block, you can group related blocks for better organizing and accurately describing test cases.

describe('Test Helpers', function () {
 /**
  * Add all your related test cases here
  *
  */
});
 
describe('Test Authentication', function () {
 /**
  * Add all your related test cases here
  *
  */
});

Excluding a suite can be done by adding `x` to the `describe` function for instance `xdiscribe()`. This will temporarily disable a suite making all the specs within the disabled `describe` block marked as pending and not executed in the report.

Specs

A spec declares a specific test that belongs to a test suite. This is achieved by calling the Jasmine global function `it()`, which takes two parameters. The spec title and a function that implements the actual test case.

A spec may contain one or more expectations used to determine the correctness of the test. Each expectation is simply an assertion that can return true or false. When an expectation returns true, the spec is passed but fails when the expectation returns false.

Here is how to declare a spec:

describe('Test Helpers', function () {
 it('should calculate Fibonacci series', function () {
   /*...*/
 });
});

We can also exclude individual specs from execution by adding x to the xit() function. Jasmine will ignore this particular test and also ignore reporting it.

Expectations

Expectations are created using the expect function. They take a value called the actual. The actual value is compared with a matcher function and returns the falsity or truthy of the comparison.

You can chain many expect() functions with multiple matchers to obtain different results from your test cases.

Here is a simple example of using the except function for comparison:

describe('Test Helpers', function () {
 it('should calculate Fibonacci series', function () {
   const fib = Fibonnaci(4);
   expect(fib).toEqual(3);
 });
});

Expectations can come in different formats depending on your use cases and the type of matchers you decide to use to obtain your result.

Matchers and Custom Matchers

Jasmine provides a rich set of built-in matchers. Let's explore some important ones:

  • toBe(): It's used for testing identity.
  • toBeNull(): It's used for testing for null.
  • toBeUndefined()/toBeDefined(): It's used for testing for undefined and not undefined, respectively.
  • toBeNaN(): It's used for testing for NaN (Not a Number).
  • toBeFalsy()/toBeTruthy(): It tests falseness and truthfulness, respectively.
  • toEqual: It's used for testing for equality.

You can find the full list of matchers from the docs.

The code snippet below shows a simple implementation of our specs with some of the matchers.

 describe('Test Helpers', function () {
it('should calculate Fibonacci series', function () {
const fib = Fibonnaci(4);
expect(fib).toEqual(5);
expect(fib).toBeDefined();
expect(fib).toBeNaN().toBeFalsy();
});
});

Jasmine provides the ability to define your custom matcher to satisfy your use case. You can create a custom assertion function not covered by the built-in matcher.

Using beforeEach and afterEach

Jasmine provides two global functions for initializing and cleaning your specs. They are the beforeEach and afterEach functions.

  • The beforeEach function is called once before each spec in the suite.
  • The afterEach function is called once before each spec in the suite.

For instance, if you need to initial variables to use in each of your test suites, you can simply add the initialization process inside the `beforeEach` function, and it will be initialized on every test case. Also, you can reset any variable of your choice using the `afterEach` function.

In the next section of this Jasmine unit testing tutorial, we will explore how to set up the Jasmine testing environment and configure Jasmine to work with our demo project setup.

How to set up the Jasmine test environment?

In the previous section of this Jasmine unit testing tutorial, we discussed the different ways to use Jasmine in your project. In this section, we will learn how to initialize your testing environment and configure Jasmine to work with our project setup.

We are going to use Jasmine as a library in this demo project. The `jasmine` module is a command line interface and code for running Jasmine specs with Node.js.

  • You can install Jasmine using npm in your project:
    npm install –Dev jasminenpm-install-dev-jasmine
  • Next, you can run the `init` command to initialize and set up Jasmine in your local project.
    npx jasmine initnpx-jasmine-init
  • The command will create a `spec` folder. Open the `./spec` folder and add all your test files. In addition, the configuration file is also found in this folder; you can configure it from there. Moreover, the configuration can be loaded from any location; also you can create a custom configuration to fix your project requirements.
  • Here are the default configuration file:

    {
    "spec_dir": "spec",
    "spec_files": [
    "**/*[sS]pec.?(m)js"
    ],
    "helpers": [
    "helpers/**/*.?(m)js"
    ],
    "env": {
    "stopSpecOnExpectationFailure": false,
    "random": true
    }
    }
    
  • After configuring the file, add the testing script to your package.json file and use the test command to run your test cases.
  • "scripts": {
    "test": "jasmine"
    }
    
    
  • Lastly, use the following to run your test suites:
    bash
    npm run test

In the next section of this Jasmine unit testing tutorial, we will follow these steps to test the registration form demo Node.js application we have created for this Jasmine unit testing tutorial.

How to test Node.js applications with Jasmine?

In this Jasmine unit testing tutorial section, we will build and test a registration form in Node.js using Express and Jasmine.

  • First, we will create a new project or clone from this repository.
  • Open the `index.html` file and add the following code if you created a new project.
  • <h1>Registration form</h1>
    <div class="form-container">
    <form name="registerForm" method="POST">
    <label for="firstName">First Name *</label>
    <input
    type="text"
    id="firstName"
    name="firstName"
    placeholder="John"
    required
    />
    <p class="error-message"></p>
    <label for="lastName">Last Name *</label>
    <input type="text" id="lastName" placeholder="Doe" required />
    <p class="error-message"></p>
    <label for="e-mail">E-mail address *</label>
    <input
    type="text"
    id="e-mail"
    placeholder="john-doe@net.com"
    required
    />
    <p class="error-message"></p>
    <label for="phoneNumber">Phone Number</label>
    <input
    type="text"
    id="phoneNumber"
    maxlength="9"
    pattern=".{9,}"
    required
    title="9 characters length"
    placeholder="223587972"
    />
    <p class="error-message"></p>
    <label for="country">Country</label>
    <input type="text" id="country" placeholder="United Kingdom" />
    <p class="error-message"></p>
    <label for="password">Password *</label>
    <input
    type="password"
    id="password"
    pattern=".{8,}"
    required
    title="8 characters minimum"
    />
    <p class="error-message"></p>
    <p class="password-rules">
    Your password should contain at least 8 characters and 1 number.
    </p>
    </form>
  • Next, add a `style.css` file and style your form to look presentable, or copy the CSS style file from the repository for this project.
  • If everything is properly set up, you should be presented with a well-formatted HTML page inspired by the Aliens' Registration Form with validation.
  • aliens-registration-form-with-validation
  • Next, we will create different test files to test the different input validation functions and test the Express server post request to make sure we have the expected result.
  • Lastly, we will add more validation functions to the helper.js file we created earlier. Here are some of the functions we added.
  • /*first name input validation*/
    function FirstName(fname) {
    var letters = /^[A-Za-z]+$/;
    if (fname.match(letters)) {
    return true;
    } else {
    return false;
    }
    }
    
    /*last name input validation*/
    function LastName(lname) {
    var letters = /^[A-Za-z]+$/;
    if (lname.match(letters)) {
    text = '';
    return true;
    } else {
    return false;
    }
    }
    
    /*email address input validation*/
    function Email(email) {
    var mailformat = /^w+([.-]?w+)*@w+([.-]?w+)*(.w{2,3})+$/;
    var atpos = email.indexOf('@');
    var dotpos = email.lastIndexOf('.');
    
    if (email.match(mailformat) || (atpos > 1 && dotpos - atpos > 2)) {
    return true;
    } else {
    return false;
    }
    }
    
    /*phone number validation*/
    function PhoneNumber(pnumber) {
    var numbers = /^[0-9]+$/;
    if (pnumber.match(numbers)) {
    return true;
    } else {
    return false;
    }
    }
    
    /*country input validation*/
    function Country(country) {
    var letters = /^[A-Za-z]+$/;
    if (country.match(letters)) {
    return true;
    } else {
    return false;
    }
    }
    
    /*validate password*/
    function Password(password) {
    var illegalChars = /[W_]/; // allow only letters and numbers
    if (illegalChars.test(password)) {
    return false;
    } else if (password.search(/[0-9]+/) == -1) {
    return false;
    } else {
    return true;
    }
    }
    

The code snippet is already self-explanatory with the use of comments. We are validating different inputs for each param passed to the individual functions.

Creating the test files

First, we will create the `validations.spec.js` file inside the newly created `spec` folder and add the following codes to cover the Validation test suites.

const {
validateCountry,
validatePassword,
validatePhoneNumber,
validateEmail,
validateLastName
} = require('../helpers');


describe('Validation Helpers', function () {
it('should validate country', function () {
const country = validateCountry('nigeria');
expect(country).toEqual(true);
});

it('should validate acceptable password', function () {
const password = validatePassword('Password1');
expect(password).toEqual(true);
});

it('should validate wrong password', function () {
const password = validatePassword('Password');
expect(password).toEqual(false);
});

it('should validate good PhoneNumber', function () {
const password = validatePhoneNumber('081456552232');
expect(password).toEqual(true);
});

it('should validate empty PhoneNumber', function () {
const password = validatePhoneNumber('');
expect(password).toEqual(false);
});

it('should validate good email', function () {
const email = validateEmail('test@test.com');
expect(email).toEqual(true);
});

it('should validate empty email', function () {
const email = validateEmail('');
expect(email).toEqual(false);
});

it('should validate good last name', function () {
const lastName = validateLastName('Solomon');
expect(lastName).toEqual(true);
});
});

The code snippet above uses the different concepts we have explained above to create a test suite for making sure our validation methods work as expected.

Running Jasmine Test

Lastly, we will run the test to see if it passes or not. Type the following command into your root terminal.

npm run test

If your test is successful, you should see three 12 cases passed, as shown in this figure.

cases-passed

In this section of this Jasmine unit testing tutorial, we have demonstrated how to configure and structure software testing with Node.js using the latest Jasmine testing library. We have also learned how to write a basic unit test.

However, you can use cloud testing platforms like LambdaTest to perform Jasmine unit testing at scale over a cloud Selenium Grid. LambdaTest offers a secure and reliable cloud-based Selenium Grid infrastructure that enables you to conduct cross browser testing on a large scale. With a vast selection of over 3000 browser and operating system combinations available on its online browser farm, LambdaTest allows you to test your code on various environments.

You can follow the LambdaTest YouTube Channel for more such videos around Selenium testing, CI/CD, Cypress UI testing, and more.

To perform Jasmine unit testing on a cloud grid-like LambdaTest, you can follow these steps:

  • Sign up for a LambdaTest account and set up your cloud grid by choosing the browsers and operating systems you want to test on.
  • Install the LambdaTest Selenium grid npm package on your local machine by running the command "npm install -g lambda-test"
  • Create a new Jasmine test file and write your test cases.
  • Execute your test cases on the cloud grid by running the command "lambda-test run --specs path/to/your/test/file.js --user [email] --key [access_key]".
  • You can check the results of your test cases on the LambdaTest platform, where you can view detailed information about test execution, including screenshots and video recordings.
  • You can also integrate LambdaTest with your CI/CD pipeline so that your tests are run automatically on every build.
LambdaTest

If you're a JavaScript developer looking to improve your unit testing skills, consider taking the Selenium JavaScript 101 certification course from LambdaTest to gain the expertise needed to excel in the field.

Summary

BDD encourages collaboration even in software testing, and Jasmine testing framework builds on these principles to deliver a collaborative testing environment for the software engineering team.

Software testing is a very important aspect of software development. It ensures that the software under test meets the intended requirement, is defect-free, and is free of errors and bugs.

In this Jasmine unit testing tutorial, we discussed the overview of Jasmine and how it implements BDD principles. We explored the different ways to use Jasmine in your JavaScript projects and elucidate the different elements of the Jasmine testing framework.

In this Selenium JavaScript tutorial, we implemented a simple registration form demo Node.js application using Expressjs. Lastly, we use Jasmine to implement the JavaScript unit testing method to validate users' input to ensure it's in the correct format.

Frequently Asked Questions (FAQs)

Is Jasmine a unit testing tool?

Yes, Jasmine is a unit testing tool for JavaScript. It is a behavior-driven development (BDD) framework that provides a suite of matchers for making assertions about the code being tested. It does not require a DOM (Document Object Model) and has a clean, obvious syntax, so it's easy to write tests. It is open-source and widely used in JavaScript development.

Is Jasmine better than jest?

Jasmine and Jest are popular JavaScript testing frameworks with different design philosophies and features. Both frameworks are powerful and widely used, so choosing between them will depend on your specific needs and project requirements.Jest is a complete testing solution. It includes everything you need to start testing, including a test runner, assertion library, and mocking library; it's also faster than Jasmine. Jasmine, on the other hand, is a bit more minimal, and it's more of a pure BDD framework, which makes it more suitable in certain contexts.

Was this article helpful?

Helpful

NotHelpful