Use Karma and Grunt to Run Your Jasmine Tests in Real-Time
As JavaScript applications become more common and more complex, the need for good unit test coverage also increases. Hopefully you’re already writing tests. If not, why not?
When I’m doing TDD with C#, I use NCrunch to monitor all tests within the Visual Studio Solution and run them as they change. This saves me having to manually run unit tests every now and again and gives me fast notifications if anything I’m writing has broken existing functionality.
NCrunch doesn’t support Jasmine unit tests so we need to find another way to handle those.
Counter
To begin with, we’ll need some code to test with. So we’ll use a simple Counter class to write tests against. In the spirit of TDD, we’ll write tests first for add, subtract and difference calculations and then add in an implementation to make the tests pass.
This is the folder structure we’ll be using:
counter.tests.js
Everything in there should be pretty straight-forward. The first reference line is to point to our implementation so that ReSharper can pick up and run the tests through Visual Studio if needed. It doesn’t effect anything we’re doing here.
Now we have our tests, we can write our code file.
counter.js
There’s currently no implementation in there, which is what we want. Before we can trust any of our tests, we need to see them fail.
How to Sell a Contradiction
Karma is a JavaScript test runner created by the AngularJS team. From the documentation:
Karma is essentially a tool which spawns a web server that executes source code against test code for each of the browsers connected. The results for each test against each browser are examined and displayed via the command line to the developer such that they can see which browsers and tests passed or failed.
Karma also watches all the files, specified within the configuration file, and whenever any file changes, it triggers the test run by sending a signal the testing server to inform all of the captured browsers to run the test code again. Each browser then loads the source files inside an IFrame, executes the tests and reports the results back to the server.
The watch functionality of Karma is going to allow us to leave it running in the background, watching for changes in any files we specify then re-running tests.
To set up Karma, we need a config file. For our requirements, it’ll look like this:
karma.conf.js
Note the basePath and files settings which are pointing at the directory containing our test file and the (still to be written) implementation.
To run the Karma tests, we need to install all dependencies and then run it. We’ll handle this using npm and Grunt.
Doing the Heavy Lifting For You
Grunt is a task runner that lets you write functionality in JavaScript and then have it run as needed. So, anything you’d like to automate, this will let you do it. It’s a very good fit for our automated testing needs.
Grunt tasks are just JavaScript files. Any additional functionality can be loaded in from libraries via an npm package.json file. The Karma team already have a Grunt task for use so we can use our package file to load this as well as Grunt, Karma and additional Karma runners. This looks like:
package.json
If you want any more information on these packages, you can look them up on the npm module directory but most should be self-explanatory.
The Grunt file itself is simple:
gruntfile.js
All we’re doing here is telling Grunt to load all packages from the package.json file then setting up a single Karma task, the settings from which are to be taken from the karma.conf.js file.
Running it All
That’s quite a bit of configuration without running anything, so let’s fire it up and see what we get.
By now, your directory structure should look like this:
If you don’t have Node.js installed, you’re not going to get very far so go and install that from http://nodejs.org/.
Once that’s done, open up the npm command prompt and cd into your runner folder within the project:
Install the required Node.js packages:
This will pull down all dependencies from the npm directory. Once that’s done (it could take a minute or two and you’ll get a lot of output on the screen), you can run your Grunt file:
If all goes well, your Grunt file will run your tests and you’ll get output something like this:
Here you can see that the 5 tests within our counter.tests.js file have been run and all fail (as expected). The runner hasn’t finished executing though as it’s now monitoring the file system for changes. We can start adding in functionality to our file and seeing how the tests update.
Open up your counter.js file and add an implementation for the add and substract methods:
When you save your changes, your command line runner should run all tests again and update the results to:
Here you can see that only 3 out of the 5 tests are now failing.
Now add in the implementation for the difference method:
Save your changes again and all tests should now be passing:
Moving On
Now that you’ve gotten this running, you can add more browsers into the test suite via Karma. Just update the browsers property of karma.conf.js.
You could also set the test runner to run on your continuous integration server using online browser testing suites. Colin Gemmel has a good write up on this using Gulp and SauceLabs browsers.
Source Code
All source for this example is available on [GitHub](https://github.com/kwilson/karma-through-grunt).