Rosher Consulting

Software Consulting and Development Services

Unit Testing AngularJS with Jasmine, Chutzpah and Visual Studio

Recently I’ve been working on a project that heavily utilised AngularJS for its client side functionality. Since all of my server side C# code was all unit tested I wanted to add some unit tests to my Angular controllers and services. Unit testing C# and server side code is well understood, with plenty of tools available and support baked in to Visual Studio, but the idea of unit testing JavaScript is reasonably new, which means that the number of tools available to a developer (especially a .NET/C# dev) is quite limited and the IDE support minimal.

Fortunately the community has been very active in this area, so everything was available for me to get unit tests added to my project, I just needed to work out how to do it.

Since I’m working with Angular, the first thing I did was look at the code samples on the Angular site, which all come with unit tests, these use the Jasmine testing framework and I came across a couple of good articles on testing Angular controllers and services using Jasmine here and here – Note that I won’t be providing example unit tests with this blog post, the examples on the Angular site and the preceding two links cover it far better than I ever could.

This all seemed straightforward so far, however I wanted to get this nicely integrated into Visual Studio, so a bit more Googling and I came across Chutzpah (pronounced hutz-pah). Chutzpah is an open source test runner which lets you integrate JavaScript unit tests into Visual Studio and enables you to run them from the command line, which means you can integrate your tests into your build process.

Installing Chutzpah

Chutzpah can be installed from NuGet, just right-click on your project or solution in Visual Studio and choose ‘Manage NuGet' packages’, then search for ‘Chutzpah’, it should be the first result found:

chutzpah-nuget

To run Chutzpah from within Visual Studio you will also need to install two plugins, the first is ‘Chutzpah.VS2012.vsix’, this integrates into the unit test explorer window in Visual Studio, the second ‘chutzpah.visualstudio.vsix’ integrates into Visual Studio’s context menu so you can right-click on a test and run it.

Resharper

If you’ve got Resharper installed then it automatically supports running Jasmine unit tests so you won’t have to install the two Chutzpah plugins above. The one thing you’ll probably want to change however is how the tests are run, by default it will run them in the local browser, but you can change this to use the PhantomJS headless browser, which is installed with Chutzpah. Just go to Resharper->Options, then Tools->Unit Testing->JavaScript Tests and change the ‘Run Tests With’ setting to ‘PhantomJS’, then browse to the PhantomJS exe, which is in the Chutzpah NuGet package folder, so mine is set to ‘C:\myproject\packages\Chutzpah.2.5.0\tools\phantomjs.exe’ as below:

resharper-phantomjs

Where to put your unit tests?

There are a number of posts on Stack Overflow (see here, here and here for example) about where to put your JavaScript unit tests i.e. should they go in the same project that is under test or should they be in a separate project? Personally I like to keep my tests separate from the actual code and all of my C# unit tests are in a separate project in my solution file, so I’ve done the same for my JavaScript unit tests.

All you need to do is add a new ‘Class Library’ project to your solution and then add the Jasmine NuGet package to that project.

Running your tests

After installing Chutzpah and creating my first set of tests, I then attempted to run them, but no matter what I couldn’t get my tests to pass. After taking a step back and writing some very simple tests with no dependencies it turned out that I just need to make sure I’d included all of the necessary references in my unit test files.

Chutzpah runs all tests in a single file in isolation i.e. think of it like each of your C# unit tests which need to include any references with ‘using’ statements, so each unit test file has to reference any supporting JavaScript files it needs. References look like the following and should be placed at the top of your test file:

/// <reference path="../../../../myproject/scripts/libs/angular.js" /> 
These are file path references, relative from the tests project to the actual file location, the easiest way to create these references is to simply click and drag the file from the solution explorer into the JavaScript test file and Visual Studio will automatically create the reference for you.

In my tests I was including the references for Angular, Angular Mocks etc., but I hadn’t taken into account any other file references I may have needed, especially as they weren’t being used by the controller/service under test. It turns out that in my ‘App.js’ file I had some JQuery code running on start-up prior to my Angular app being created, which meant that in my tests I had to reference some extra files otherwise my Angular app module couldn’t be created and hence my tests would fail, which wasn’t entirely obvious from the test results (and of course I realise now that including non-Angular code in an Angular file was a bad idea!).

Here’s the list of references I ended up having to include, which as you can see is quite a lot for what was a simple unit test:

/// <reference path="../../../../myproject/scripts/libs/angular.js" /> 
/// <reference path="../../../scripts/angular-mocks.js" /> 
/// <reference path="../../../../myproject/scripts/libs/ui-bootstrap.js" /> 
/// <reference path="../../../../myproject/scripts/libs/sanitize.js" /> 
/// <reference path="../../../../myproject/scripts/libs/jquery-1.9.1.js" /> 
/// <reference path="../../../../myproject/scripts/libs/bootstrap-datetimepicker.js" /> 
/// <reference path="../../../../myproject/scripts/libs/jquery.validate.js" /> 
/// <reference path="../../../../myproject/scripts/app/app.js" />

Once I’d included the above references, my tests all ran fine as you can see in the following screenshot from the Resharper unit test session window:

resharper-js-test-run

 

Integrating your tests into your build

Chutzpah comes with a console application, which means that you can run your JavaScript unit tests from the command line, all you have to do is point it to the folder where your tests are, like so:

chutzpah.console.exe C:\MyProject\MyJavaScriptTests\

One issue I found is that Chutzpah will look for all JavaScript files in that folder and sub-folders, meaning that since we’ve installed Jasmine into our project, Chutzpah will also attempt to load and run those files, which we don’t want. Unfortunately Chutzpah doesn’t support filtering or wildcards in the folder path you specify, so the way I got around this was to place all of my tests into a subfolder and then adjust the command line to point to this folder instead, bypassing any files I didn’t want tested:

chutzpah.console.exe C:\MyProject\MyJavaScriptTests\Tests\

chutzpah-console

Adding Chutzpah to your Msbuild project

Since Chutzpah can be run from the command line, adding it to your build project is straightforward, all you need to do is create an ‘Exec’ task that executes the console application with the appropriate path to your JavaScript unit tests:

<Target Name="RunJSUnitTests">
  <Exec Command="&quot;$(SolutionFolder)\packages\Chutzpah.2.5.0\tools\chutzpah.console.exe&quot;
 $(SolutionFolder)\Tests.JavaScript\Tests\ /silent
 /junit $(MSBuildProjectDirectory)\chutzpah-output.xml" 
WorkingDirectory="$(SolutionFolder)\packages\Chutzpah.2.5.0\tools\" />

  <Message Text="$(TASK_BREAK)" />
</Target>

Here’s the result of running the above build task on my system, if any of the JavaScript tests fail, Chutzpah will return an error and the build will fail:

chutzpah-msbuild

Team City

Chutzpah automatically detects when it’s being run inside Team City and will change its output to the format understood by Team City, so as long as Chutzpah has been added to your Msbuild project, you don’t need to do anything to get support inside Team City as you can see from the following build log:

team-city

Summary

As you can see, there really aren’t that many steps involved in getting JavaScript tests setup in both Visual Studio and your build process, really the hardest thing for me was figuring out why my tests were failing and that was merely making sure my references were setup correctly, other than that everything was surprisingly straightforward, certainly more so than I was expecting when I started on this journey.