Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Writing Web-Based Client-Side Unit-Tests With Jasmine and Blanket

DZone's Guide to

Writing Web-Based Client-Side Unit-Tests With Jasmine and Blanket

In this article, we'll go over two JavaScript-based packages for writing unit tests, the code behind them, and when best to use each.

· Web Dev Zone
Free Resource

Tips, tricks and tools for creating your own data-driven app, brought to you in partnership with Qlik.

Preface

When writing a website, or more often - a one-page app - there is a need to test it, just like any other piece of code.

There are several types of tests, of course, including unit tests and integration tests.

While integration tests test flows of the entire application, end to end, and thus simulate user interaction (which requires a special browser-based testing package), unit tests run specific functions.

However, when writing an entire application in JavaScript, running pieces of code is a bit more tricky.

On one hand, we are not used to writing unit tests in JavaScript and running the tests completely in the browser. On the other hand, calling JavaScript code and then testing various members for values is much more easily done when written directly in JavaScript.

Luckily, the good people of the web have given us several JavaScript-based packages for writing unit tests. I'll talk about Jasmine, and add some words about Blanket, that integrates with Jasmine to perform code coverage.

Jasmine

Jasmine is a JavaScript based library to perform unit tests. It consists of several parts:

  1. The Runner.
  2. Tests Framework.
  3. Plug-ins.

1. The Runner

The runner is an HTML file with base code that loads the tests framework and runs the tests. It will not do anything when you take it out-of-the-box. You have to add your own scripts in there, so consider it a template.

The base HTML looks like this:

<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">

<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/boot.js"></script>

Next, you need to add your own application scripts:

<script type="text/javascript" src="src/myApp.js"></script>

And finally comes your tests scripts:

<script type="text/javascript" src="tests/myAppTestSpec.js"></script>

2. Tests Framework

Jasmine has several files that create the tests framework. The most basic ones are the one listed above, in the basic HTML example. Let's go over them quickly: 

jasmine.js

The most basic requirement. This is the actual framework. 

jasmine-html.js

This one is used to generate HTML reports. It is a requirement, even if you don't want HTML reports. 

boot.js

This one was added in version 2.0 of Jasmine, and it performs the entire initialization process. 

Writing Tests 

Structure

The unit tests in Jasmine are called "Specs," and are wrapped in "Suites." It looks like this:

describe("A suite", function() {
  it("contains spec with an expectation", function() {
    expect(true).toBe(true);
  });
});

The  describe  function describes a test suite, while the it function specifies a test.

Note that, as parameters, those two get a name and a simple function block, and that the it block is being called in the body of the describe function block. This means you can store "global" members for each test suite. Also, it means that the tested code comes inside the it block, along with any assertions. 

Expectations (a.k.a. Asserts in Other Test Suites)

When writing a unit test you expect something to happen, and you assert if it doesn't. While in other test suites you usually use the term Assert to perform such operation, in Jasmine you simply Expect something.

The syntax for expectations is straight forward:

expect(true).toBe(true);

There are many "matchers" you can use with the expect  function, including, but not limited to:

  •  toBe  - test the value to actually BE some object (using '===').
  •  toEqual  - test the value to EQUAL some other value.
  •  toMatch  - tests a string against a regular expression.
  •  toBeDefined/ toBeUndefined  - compares the value against 'undefined'.
  •  toBeTruthy/toBeFalsy  - tests the value for JavaScript's truthiness or falsiness.
  •  toThrow/toThrowError  - if the object is a function, expects it to throw an exception.

You can also negate the expectation by adding not between the expect and the matcher. 

Spies

You can also use Jasmine to test if a function has been called. In addition, you can (actually, need) to define what happens when the function is called. The syntax looks like this:

spyOn(someObject, "functionName").and.callThrough();
spyOn(someObject, "functionName").and.returnValue(123);
spyOn(someObject, "functionName").and.callFake( ... alternative function implementation ... );
spyOn(someObject, "functionName").and.throwError("Error message");
spyOn(someObject, "functionName").and.stub();

Then, you can check (expect) if the function was called using:

expect(someObject.functionName).toHaveBeenCalled();

or

expect(someObject.functionName).toHaveBeenCalledWith(... comma separated list of parameters ...);

More Info

There are many features you can use with Jasmine. You can read all about it in the official documentation at here.

3. Plug-ins

Well, I'll only talk about Blanket, the code coverage utility that integrates with Jasmine.

In the runner, add the following line before the tests specs scripts, but after the application scripts:

<script type="text/javascript" src="lib/blanket.min.js" data-cover-adapter="lib/jasmine-blanket-2_0.js"></script>

And that's it!

Below the test results report there will be the code coverage report.

The blanket.js package can be found at here, and the adapter for Jasmine 2.x can be found at here (unfortunately, blanket.js only comes pre-packaged with an adapter for Jasmine 1.x).  

Happy Coding!

For more insightful articles, click here

Explore data-driven apps with less coding and query writing, brought to you in partnership with Qlik.

Topics:
client side ,jasmine ,web dev ,unit testing

Published at DZone with permission of Adi BatSheva. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}