Tuesday, November 24, 2015

JavaScript Unit Testing in Visual Studio Team Services(VSO)

JavaScript unit testing can be a real struggle. Especially when you want to integrate unit testing into your continues delivery and/or continues deployment. This blog post is about enabling your JavaScript unit tests to run on Visual Studio Team Services.

Unit testing your web application is hard, you probably got to deal with one or multiple data connections, server side code such as ASP.net(C#) and front-end JavaScript code which is fully integrated into your HTML templates. Regardless of the code that has to be unit tested you got to mind several design principles, namely:

  1. Separation of Concerns
  2. Dependency injection
  3. Build integration

This blog post isn't about the first and second principle but all about the 3rd one, namely Build Integration. This post therefore presumes that you have a working set of JavaScript unit test using a framework such as: QUnit, Jasmine and Mocha.

So why Build integration? Well having your unit tests integrated in your automated build flow is a must have for every web developer. The time that we manually build and unit test our code is over. If you are still doing that, then that's a big sign for you to critically look at your workflow. You are literally living in the past!

Most of you developers know how to unit test your .NET code. Microsoft got great tools in Visual Studio and TFS/VSTS(VSO) to automatically run your unit tests and flag the build as a failure if one of your tests fail. This will result in finding issues earlier in the development process and thus probably better quality and faster development.

So why are we not unit testing our JavaScript, and if we do why don't we integrate it in TFS/VSTS? Well because its a little bit more complicated than unit testing .NET code. JavaScript code obviously runs in a browser, TFS/VSTS should spin up a browser and run your unit tests and then check if they succeeded or failed. Well that's the exact problem, TFS/VSTS doesn't support that functionality and that leaves us hanging to automate our JavaScript unit tests.

But wait! what about all those server side JavaScript instances such as NodeJS, can't they tackle this problem for us? Well actually they can! NodeJS provides great functionality to run your JavaScript unit tests on the NodeJS runtime but the only problem is, is that NodeJS doesn't got a DOM. In fact it doesn't even support document.getElementById, which will cause a lot of unit tests to fail. Well luckily for us there's PhantomJS. PhantomJS is a headless in memory browser with a DOM. It actually renders the DOM but doesn't paint it. So that tackles the problem.

But how do we get PhantomJS to work in TFS/VSTS? Well you don't have to do anything. Someone at Microsoft fixed that for us and named it Chutzpah. Chutzpah is both a Visual Studio extension aswell as a NuGet package. It contains PhantomJS as a dependency and comes with 3 JavaScript unit test libraries, namely: Jasmine, QUnit and Mocha. Its able to run and debug your JavaScript unit tests via the Visual Studio and TFS/VSTS interface, that means that you get both your .NET as JavaScript test results in one unified standard. Which is great for build purposes.
So how does it work? Well just search for Chutzpah in the Visual Studio Extensions and you will find two extensions. The first is the Test adapter, its used to run tests in the Visual Studio Test Explorer. Once you've installed the Test adapter, you will see that your JavaScript unit tests will be picked up in the explorer. Just select your tests and spin it up, you will see that your tests will integrate perfectly within Visual Studio.
The second extension is a context menu extension that allows you to run your tests within two mouse clicks. This plugin also provides you additional functionality such as code coverage results, using blanket.js. It produces really nice code coverage files that exactly pinpoint the code that hasn't been hit.

It will be easy to get your unit tests to run on TFS/VSTS, once your unit tests run within Visual Studio. First crab the NuGet package. The NuGet package, as stated earlier, has the necessary files to run your unit tests, this also applies to TFS/VSTS. Secondly add a Visual Studio test build step to your build flow.
Once you've done that make sure that you adjust to test assembly to only match JavaScript test files. Normally I suffix these files with *.tests.js. This makes them easy to find and apply in the build step. Note that we have to exclude all files that are found in the obj folder. Otherwise you will have double tests. The screenshot contains the following line: **\*.tests.js;-:**\obj\**\*.tests.js

Lastly make sure that you point to the Chutzpah test adapter. This actually points to the NuGet package that you've installed for your project. Make sure that the $(Build.SourcesDirectory) has the packages folder or you might up ending with strange errors. 

Well and that's it. Hopefully you've had enough information. If you have any questions or problems feel free to contact me.