How to enable JavaScript Code Coverage When Using Rails, CircleCI, AngularJS, Jasmine and Teaspoon

I am a big fan of code coverage.  Enough has been written about the need of the same. It helps raise confidence within development teams, solidifies the unit testing process and alleviates some risks that lurk when there is not a plethora of quality assurance resources. When this is coupled with good peer code review and inspection practices that come with say Git Pull Requests or Atlassian Crucible, you can be certain to a good degree that the funtionality at least at the unit level is not brittle. Even though it is metrics vs inspections, I find that investment in keeping a track of code coverage metrics is better than having Fagan Inspections or reading code line by line with the whole team sitting around a table while taking multiple coffee breaks.

I have played with Emma and Cobertura earlier. But, recently I found myself in a spot where I needed to review code coverage metrics for JavaScript assets within a Rails based app. This may have been done before, but the combination seemed unique to me. The app is a heavy Ruby on Rails, JavaScript is AngularJS based, unit tests are defined using Jasmine and we are run using Teaspoon as the test runner. Builds are deployed on CircleCI. Coverage needs to run locally and as part of the continuous integration builds. Unless your app setup is completely non-standard, the following steps are what you would need to enable code coverage. Of course you may be using a different Javascript library or Karma instead of Teaspoon.

Note that I am working with a sexy MacbookPro. So if you are using a Windows machine (bless your heart) the commands may not be that different. Please feel free to add those as comments if you end up trying this on Windows.

Now, let us first walk through the steps you will need to get going locally.

1. Install Node.JS. We need it to run Istanbul, the engine that will actually instrument the code.

2. Teaspoon depends on Istanbul for coverage. Install it as:

npm install -g istanbul

3. Edit the Gemfile of your Rails app and enable the phantomjs gem as :

group :development, :test do
  ...
  gem 'phantomjs'
  ...
end

FYI…phantomjs is a headless WebKit browser.

4. Now run bundle install to make sure phantomjs is installed.

bundle exec teaspoon

5. Edit teaspoon_env.rb and enable at least these lines in the coverage area:

#...
config.use_coverage = nil
config.coverage do |coverage|
  coverage.reports = ["html"]
  #Which coverage reports Istanbul should generate...

6. Now, in order to test and generate a default configuration report locally, do:

bundle exec teaspoon --coverage=default

Report is generated under coverage folder in folder, by the name of the configuration you specified. There you will find index.html, open it and viola!

ksarneja-coverage

Now, to get the same effect going for CircleCI build (that is cloud baby!) you first have to tell the CircleCI environment that coverage is on. This is done through circle.yml

So edit that file and add these following line under dependencies / pre section. This will install Istanbul as part of the CI build, if it has not been done on a higher level.

- npm install -g istanbul

Also in test / post section, enable coverage and then copy the artifacts to the default CIRCLE artifacts location. Note that this may be different for you. No point make this a parallel task as teaspoon tests (if well written) are execute very quickly. But note that copy should be done after the Teaspoon tests have run. In other words, the commands are sequential.

- bundle exec teaspoon --coverage=default
- cp -r ./coverage/default $CIRCLE_ARTIFACTS

Run the build. When it has run successfully, check the Artifacts tab and scroll down for index.html.

ksarneja-ciartificat_1

More configuration options and settings can be set in teaspoon_env.rb. You may check out the teaspoon gem site for more settings.

Cheers!

Leave a comment