Agile Zone is brought to you in partnership with:

I am a programmer and architect (the kind that writes code) with a focus on testing and open source; I maintain the PHPUnit_Selenium project. I believe programming is one of the hardest and most beautiful jobs in the world. Giorgio is a DZone MVB and is not an employee of DZone and has posted 637 posts at DZone. You can read more from them at their website. View Full User Profile

Testing and specifying JavaScript code with Jasmine

12.07.2011
| 5491 views |
  • submit to reddit

Jasmine is a BDD framework for JavaScript (or CoffeeScript) code, which helps you specify and test your classes and functions as the same time.

Jasmine is not derived from the classic xUnit API, but features Behavior-Driven Development syntax, composed of easy and short method calls.

The framework is developed by Pivotal Labs, the same company behind Pivotal Tracker (one of the few the Agile planning tools that allegedly works) and Pivotal CRM. Wikimedia Commons and Diaspora, just to make some example, use Jasmine and I learned about its diffusion at the last Global Day of Code Retreat.

I already have jsTestDriver!

On the why another testing framework side, the documentation makes some compelling points

  • Jasmine is not tied to a browser or even to browsers in general: it can run anywhere JavaScript is supported, so also in the console.
  • Its API is simple (the same for jsTestDriver) and has a short learning curve: after some minutes you will be able to run almost any unit test.
  • The framework does not clutter the global namespace, or jump through horrible hoops that static analysis of code will continuously point out.

Where to run it

There are several options for running Jasmine:

  • in the browser; an HTML file loads all the .js files and shows you the result of the suite. Jasmine also has an interactive console for trying out its syntax, linked in the resources.
  • In multiple browsers, with jsTestDriver as a backend.
  • Via a gem for Ruby or Coffeescript adopters.
  • Via console, in the case of Node.js apps.

The browser usage is actually the most straightforward: you just need to edit SpecRunner.html by adding <script> tags for your source files and specs.

Here is how Jasmine looks like after I ran it from a git checkout (you'll need to edit the paths of the example SpecRunner.html file in this case):

How Jasmine looks like

Writing tests specifications with Jasmine is really simple:

describe('prime numbers detector',function(){
  it('avoids 1',function(){
    expect(isPrime(1)).toBe(false);
  });
  it('detects 2',function(){
    expect(isPrime(2)).toBe(true);
  });
  it('detects 3',function(){
    expect(isPrime(3)).toBe(true);
  });
  it('avoids 4',function(){
    expect(isPrime(4)).toBe(false);
  });
});

This code sample describes an isPrime() function, but you can run any kind of JavaScript code inside the anonymous functions passed to it(). You can also add a beforeEach(function() {}) call before the it() ones, to specify a setup common to all tests.

toBe() is an universal matcher, but there are many others to keep your spec readable:

  • expect(x).toBeNull(), expect(x).toMatch(/[A-Z]*/), expect(x).toBeLessThan(42) are all examples of dealing with non numerical variables.
  • expect(function() { fn(); }).toThrow(e) allows you to specify an expected exception.
  • expect(x).not.toEqual("hello") is a general pattern (expect(x).not) that you can use in place of expect(x) to invert the matcher's behavior.

The really handy stuff

Jasmine contains primitives for organizing tests involving asynchronicity:

  • run() is the basic element, specifying a piece of code to be executed.
  • waits(timeout) can be inserted between run() blocks to provide a cushion of waiting, difficult to obtain since JavaScript lacks sleep functions.
  • waitsFor(fn) checks repeatedly a condition, ensuring execution is continued only after it is reached.

The concept of waitsFor() is similar to Selenium 2 explicit waits, but can be used for testing just the JavaScript part and not the whole application (by faking the server-side for example). Jasmine is a solution oriented to JavaScript code and not to end-to-end tests.

Asynchronicity is highly involved in Ajax calls but also in rendering and other logic in complex frameworks like ExtJS, which is full of deferred calls. Outsourcing to the framework the complexity of testing asynchronous code is generally a positive.

Other resources

The official page for Jasmine contains multiple download packages for running it in browser or console environments. It also links to development pages on Github and to API Documentation.

You can try out Jasmine (but not saing your code) right after having finished reading this article., if "downloading a zip file is too much work!" The mailing list for Jasmine is also rather active.

Nettuts+ has a long example of the BDD/TDD cycle with a sample project to download and run. There's never enough code samples when we need them. Jared Carroll explains how the integration of the framework with jQuery (where needed).

Published at DZone with permission of Giorgio Sironi, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)