Javascript async testing tutorial: Jasmine + Rails 3.1 + Coffeescript

I recently wanted to create automated testing for coffeescript code in Rails 3.1, including some async (ajax) code. I had to dig around quite a lot, so I’m writing here what I ended up doing for future reference for myself and others who might need it.

There are many test frameworks for javascript, and the one I chose is Jasmine. Reason why: It is one of the two most used frameworks, and the other one is dependent on jQuery. I’m using jQuery in this project, but I’ll be able to use Jasmine for future projects without jQuery too, so I chose it – I also like its syntax.

You can integrate Jasmin in Rails 3.1 yourself just using the Jasmine gem, but to simplify things with Coffeescript I decided to use a specific gem for the latest version of Rails and its assets pipeline. I couldn’t really choose between test_track and jasminerice, which are both very young, so I went with the first one just based on intuition. Using the other one shouldn’t be very different.

So, I added to my gemfile:

gem "jasmine"

gem "test_track"

and installed the new gems with “bundle”

I then created a spec/javascripts and spec/javascripts/helpers folder in the project tree. As I wanted to be able to easily test jQuery, I downloaded jasmine-jquery.js from github and copied it into spec/javascripts/helpers.

At this point I created the following jasmine.js file om spec/javascripts:

// SUITE :: Jasmine
// SUITE MANIFEST :: spec/javascripts/jasmine.js
// TEST SRC DIR :: spec/javascripts
//= require helpers/jasmine-jquery
//= require JsonDataSpec

JsonDataSpec is the coffeescript spec file that I was going to create and that will be executed in the test. See the following example


describe "JsonData", ->
  it 'should should have the correct format', ->
    answer = null
      (data) ->
        answer = data

    waitsFor ->

    runs ->
      expect(typeof answer.string).toEqual('string')
      expect(typeof answer.number).toEqual('number')

The secret here is waitsFor -> answer, which will wait until the answer variable gets a non null value – that is, when the ajax call is complete. Only after that the actual test is run.

Last thing, I configured the test_track engine adding this code to routes.rb:

mount TestTrack::Engine => "test"

And that’s it! To use my tests, I just run the server using rails s and access the tests opening http://localhost:3000/test/jasmine in the browser. Smooth and easy.

Happy testing!