TechnologyNov 05, 2014

Testing With AngularJS Part 3: Karma and Grunt

Maria Knabe

This is the third post in my series explaining the lessons I learned when configuring unit and end-to-end testing with AngularJS.  In the previous two posts,  I covered how to configure Karma and a few useful Karma plugins. In this post, I will cover how to configure Grunt and Karma to run your unit tests as part of a build process.

What Is Grunt?

Grunt is a task runner that simplifies the automation of repetitive tasks. For example, Grunt can compile SASS files, concatenate, uglify, and minify all CSS and JS files, and execute unit and E2E tests all with one command.

Executing Tests With Grunt

Setting up Karma to run with Grunt is as easy as installing a few Grunt plugins and configuring their settings.

Use npm to install Grunt globally and install the grunt-karma plugin.

# Install Grunt globally npm install -g grunt-cli

install karma plugin

npm install grunt-karma --save-dev

Configure the task in the Gruntfile.js. I added the unit target to the Karma task, which will run the unit tests once.

module.exports = function(grunt) { grunt.initConfig({ karma: { options: { // point all tasks to karma config file configFile: 'config/karma-conf.js' }, unit: { // run tests once instead of continuously singleRun: true } } });

// load the Grunt task grunt.loadNpmTasks('grunt-karma'); };

Run grunt karma:single in the console. You should see Chrome launch (or whichever browser you configured) and the following console output if all the tests succeed. That’s it! Now this Grunt task can be used to create custom tasks as well. If tests fail, Karma will give details about those tests and the build will break.

Karma and Grunt Watch

Similar to Karma’s autoWatch option, you can also use Grunt watch to execute unit tests whenever a file changes. grunt-contrib-watch is a powerful Grunt plugin that will run tasks and refresh the browser after certain files have been changed.

Install the grunt-contrib-watch plugin.

npm install grunt-contrib-watch --save-dev

Add the task configuration to your Gruntfile. Grunt watch is configured by defining an array of files to watch and an array of tasks to run when those files change. We want to watch for changes on any JavaScript or test spec files. Whenever these files change, we tell Grunt to re-run our unit tests.

I have also set up another target called continuous that uses the background option. This allows Karma to keep running in the background.

module.exports = function(grunt) { grunt.initConfig({ karma: { options: { configFile: 'config/karma-conf.js' }, unit: { singleRun: true }, continuous: { // keep karma running in the background background: true } }, watch: { karma: { // run these tasks when these files change files: ['app/js/**/*.js', 'test/unit/*.js'], tasks: ['karma:continuous:run'] // note the :run flag } } });

grunt.loadNpmTasks('grunt-karma'); grunt.loadNpmTasks('grunt-contrib-watch');

grunt.registerTask('unit-test', ['karma:continuous:start', 'watch:karma']); };

Run grunt unit-test task in the console. Now it will execute the unit tests again whenever the JavaScript files or unit test specs change. As you are developing, you will know as soon as you break a test. When a test breaks, the watch task continues, allowing you to make fixes without having to restart the Grunt task.

Note: If you are using Chrome, the browser window will stay open. Do not minimize this window. Chrome is configured to allocated fewer resources to minimized windows, so the tests will run very slowly. Keep the window open to avoid this.


Now you should have Karma completely up and running with your project. You know how to install plugins to extend Karma and you can set up Karma to work with Grunt. In the next two posts I will explain how to set up Protractor for end-to-end testing.

Be sure to check out the example app for a full, working implementation.