Angular Unit Testing - Getting setup with Jasmine, Karma, and Grunt

Tuesday, June 24, 2014

As a developer coming from an ASP.Net, C# background, I had come to appreciate the ability to be able to unit test my code. I find that I am not all that great a programmer, and often times the unit tests I write have brought to surface a bug that I would have introduced had I not had a unit test in place to discover the bug in the first place.

In the past, I had not given much thought to do JavaScript unit tests. I had just assumed that it wasn't really possible to do them without a lot of jumping through hoops. However, with AngularJs, unit testing isn't all that difficult. I have found that once I have gotten over the initial hurdle of getting everything setup, unit testing JavaScript code has become quite useful.

I find the feedback loop is much quicker with the unit tests I write, because I can see write away that the code is working or not without having to do much of anything.

So with being said, lets look and see how to setup the unit testing framework.

NodeJs

For my unit tests, I use Jasmine, Karma, Grunt which all sit on top of the NodeJs runtime, so for that you will first need to install NodeJS.

NodeJs comes with package installer called NPM. Similar to Gems in Ruby, or Nuget in Visual Studio, NPM will install all the packages needed to start unit testing.

Note, if you are starting a project from scratch, I would recommend installing Yoeman. Yoeman is a scaffolding package that will install a starter project with everything already configured.  For example, when I have a new AngularJs project, I use the Yoeman Angular Fullstack generator, and then go back in and finegle the generated code to my own preferences.

For this post I am assuming that the project and tests already exists. So I am going to only go though all the steps to to get up and running with unit testing on an existing project.

Also, I am running Windows 8.1, so if you are on a different OS like Linux or Apple OS, or even a different version of windows, these steps might differ slightly. I'm not really sure, but I had noticed that other posts were slightly different than what I had to do to get started.

Creating the package.json File

The first thing to do is create a package.json file. NPM uses this file to keep track of what you have installed and what versions of the packages you are using. The easiest way to create this file is to initialize NPM from the command line.

npm init

Doing this generates a file that will look like this.

 

You could also just manually create the file yourself. Either way, this file is required.

Installing the packages

You can install each package separately from the command line but an easier way to get everything installed is to get a copy of the packages.json file with all the packages you need and just type the following from the command line:

npm install

This command will take what ever you have in the package.json file and install it in your project if it isn't already installed.

 

My package.json file looks like this:

The packages under the "devDependencies" node tells NPM that these are packages are only for use in the development environment and are not to be copied to production.

You might also want to install Grunt, Karma and maybe even Yoeman globally so you don't have to keep installing it for every project. You can do that with the following commands.

npm install -g grunt-cli

npm install -g karma-cli

npm install -g yoeman

The "cli" suffix is the package that allows grunt and karma to called directly from the command line in Windows. The -g parameter tells NPM you want to install the package globally.

Initializing the karma.config.js File

Karma is a test runner developed by the AngularJs team. It's basically the engine that goes through all the unit test and runs them, and then provides the results of the executed unit tests. Once karma is installed, you will need a karma.config.js file to so karma knows things where the JavaScript files are located, what testing framework you want to use, etc.

You can generate a karma.config.js file by running the following command:

karma init

When you run this you will be asked a bunch of questions:

  • Which unit testing framework do you use?
  • Do you want to use Require.js?
  • Do you want to capture any browsers automatically?
  • What is the location of your source and test files?
  • Should any of the files included by the previous patterns be excluded?
  • Do you want karma to watch all the files and run the tests on change?

I typically accept all the defaults, and, if needed, go back and change the configuration later. My current file looks like this:

If you have separated your JavaScript framework files from your own custom JavaScript files, you will need to add what ever framework files you are using that are included in the tests. For example, I have included angular and angular-mocks for angular specific testing and I also have a reference to lodash.js.

Configuring Grunt

Gruntjs is a task runner that lets you run several tasks at once. For this demo, I am only running karma, but I could add other tasks like JsHint to check my JavaScript syntax, or Uglify to minimize files. Grunt needs a gruntfile.js file installed which tells grunt what tasks to run and how to run them.

My grunt file is pretty simple since I am only running one task. It looks like this:

   

Now I'm ready

Now that I have setup my Grunt file, and I have told Karma to watch my JavaScript files. Every time I make a change to JavaScript code and change it, Karma will run the test and provide me the results in the command window. I simply run "grunt" from the command line.

Running "karma:unit" (karma) task
[2014-06-24 11:14:00.421] [INFO] karma - Karma v0.12.16 server started at http://localhost:9876/
[2014-06-24 11:14:00.569] [INFO] launcher - Starting browser Chrome
[2014-06-24 11:14:04.015] [INFO] Chrome 35.0.1916 (Windows) - Connected on socket aX-CPdsznQq6Oi75cNhf with id 3608593
Chrome 35.0.1916 (Windows): Executed 19 of 19 SUCCESS (0.047 secs / 0.043 secs)


Conclusion

I think in future posts, I will discuss a little how I go about writing unit tests, but for now I'll leave you with this in the hope that at least gets you started in writing AngularJs unit tests.

If you have any questions or feedback, shoot me a comment I would glad to hear what you think?

 

comments powered by Disqus