Jasmine HTML report
Client-side development has long become the norm, while the amount and complexity of JavaScript code is continually increasing. More often testing is performed on server side, however client code testing is of equal importance. For testing JavaScript on client-side, as well as for Node.js, you can efficiently use Jasmine.

Jasmine is a BBD (Behavior-Driven Development) framework for testing JavaScript code, that has adopted many of its traits from RSpec.

For your convenience, we will examine testing in a browser environment, whereas the provided examples will be written in CoffeeScript (examples in plain JavaScript).

Jasmine can be installed by downloading Jasmine standalone package. The following files will be required:

  • lib/jasmine-*/jasmine.js – the framework itself
  • lib/jasmine-*/jasmine-html.js – formatting results in HTML
  • lib/jasmine-*/jasmine.css – view styles for test results
  • SpecRunner.html – file that must be opened in the browser in order to run the tests

The basic keywords in Jasmine framework are:

  1. describe – defines the test suite; suites can be nested
  2. it – defines the test within a test suite
  3. expect – defines the asserted expectations in the test

The keywords describe and it are standard function calls which take two parameters. The first parameter is the name for a spec suite or test, the second – is a function that contains the code block. Now let's go through a simple example describing the above syntax:

describe "Test Suite", ->
  it "has expectations", ->
    expect(1 + 2).toBe(3)

In order to disable a test suite or a specific test you can use the keywords xdescribe and xit, respectively.

describe "Disabled", ->
  xdescribe "disabled suite", ->
    it "will not run, since the suite has been disabled", ->
      expect(true).toBe(true)

    xit "disabled test", ->
      expect(true).toBe(true)

Jasmine has a standard set of matchers that assert whether the expectation is true or false:

 it "compares using ===", ->
    expect(1 + 2).toBe(3)

  it "compares variables and objects (including content)", ->
    a = {x: 8, y: 9}
    b = {x: 8, y: 9}
    expect(a).toEqual(b)
    expect(a).not.toBe(b) # negation – a is not b

  it "checks value to be defined", ->
    expect(window.document).toBeDefined()

  it "checks value to be undefined", ->
    expect(window.notExists).toBeUndefined()

  it "checks value to be null", ->
    a = null
    expect(a).toBeNull()

  it "checks value to be true", ->
    expect(5 > 0).toBeTruthy()

  it "checks value to be false", ->
    expect(5 < 0).toBeFalsy()

  it "checks value to be less than", ->
    expect(1 + 2).toBeLessThan(5)

  it "checks value to be greater than", ->
    expect(1 + 2).toBeGreaterThan(0)

  it "checks value to be close to", ->
    expect(1.2345).toBeCloseTo(1.2, 1)

  it "checks RegEx match", ->
    expect("some string").toMatch(/string/)

  it "checks inclusion", ->
    expect([1, 2, 3]).toContain(2)
    expect("some string").toContain("some")

  it "throws exception", ->
    func = -> window.notExists.value
    expect(func).toThrow()

In order to avoid any duplication, such as object creation/deletion and fixtures loading required to run the specs, you can use beforeEach/afterEach functions. They are called before/after each test in the suite.

describe "Setup/Teardown", ->
  val = 0 # defining variable in test suite context

  beforeEach ->
    val += 1

  afterEach ->
    val = 0

  it "uses val", ->
    expect(val).toEqual(1)

Jasmine also supports testing of asynchronous calls using the functions runs and waitsFor:

  1. runs – takes the asynchronous function for execution;
  2. waitsFor – takes three parameters: the first one – is a latch function that should return true if the asynch call made in runs was executed, the second one – is a failure message, and the last one - is the waiting time in milliseconds.
describe "Asynchronous", ->
  a = 0

  async = ->
    setTimeout((-> a = 5), 1000)

  it "asynch executes code", ->
    runs(-> async())
    waitsFor((-> a == 5), "the value should be changed", 3000)

In our next article about Jasmine, we will analyze how to use spies and mock clock. If you have any questions or remarks, we will be happy to hear them.

Reference:

github.com/pivotal/jasmine – project page on GitHub
github.com/inex-finance/blog-examples/tree/master/jasmine – code examples used in this article


Published at January 25, 2013 17:43
Updated at January 31, 2013 13:44

comments powered by Disqus