Unit testing AngularJS with Visual Studio, ReSharper and TeamCity

Unit testing #AngularJS with #VisualStudio, ReSharper and #TeamCity by @MikeLarah

  • The post will go through how to write unit tests for your AngularJS app using Jasmine , how to run those tests in Visual Studio with ReSharper and the PhantomJS headless browser, and how to add a build step to your TeamCity CI pipeline to run the tests.
  • We can now use PhantomJS to load this HTML page and run the tests.
  • In the of the HTML file we include the Jasmine CSS and JS scripts, Angular JS scripts, and our app and test JS scripts.
  • factory(‘Dog’, function () { var dogs = [ { type: “Labrador”, name: “Rover” }, { type: “Tibetan Terrier”, name: “Joey” }, { type: “Yorkshire Terrier”, name: “Rufus” } ]; return { query: function() { return dogs; }, add: function(dog) { dogs.push(dog); } }; }); }());
  • You can nest test suites, and can use beforeEach to execute a piece of code before each spec in that test suite.

endjin are a full-service design, experience, development & cloud consultancy, with deep experience of technology and a broad business expertise. endjin loves solving business problems by the smart application of technology and design

@endjin: Unit testing #AngularJS with #VisualStudio, ReSharper and #TeamCity by @MikeLarah

This post will go through how to write unit tests for your AngularJS app using Jasmine, how to run those tests in Visual Studio with ReSharper and the PhantomJS headless browser, and how to add a build step to your TeamCity CI pipeline to run the tests. The source code for the demo app is available in over on GitHub.

scripts.

For this demo we will create a simple app with a controller and a service, and modules to add them to.

First, create modules for your controllers and services:

And create an app to host the modules:

Now we’ll create a basic service and add it to our services module:

And a basic controller into which we’ll inject our service:

Jasmine is a BDD (Behaviour Driven Development) framework and is the framework chosen by the Angular team for use in their documentation samples. Other frameworks could be used but Jasmine provides the functionality that we require.

as content as we will use them later.

to execute a piece of code before each spec in that test suite.

and describe a suite for all our services, and nest a suite for our specific service:

to instantiate an instance of our service. With our service instantiated, we can then write our expectations against the service.

, as well as the necessary application scripts for the test – this will give you IntelliSense in Visual Studio.

, describe a suite for all controllers, and nest a suite for our specific controller:

Now that we have some unit tests, we need a way of running them. One way of doing this is by configuring ReSharper to use PhantomJS to run them. You can also configure ReSharper to use the browser, but PhantomJS is headless, so will not pop open a browser window every time you want to run your test suite.

To configure ReSharper to run the tests, firstly you will need to download the PhantomJS executable and place this on your local drive somewhere. Then, in Visual Studio, go to the ReSharper options and navigate to Tools -> Unit Testing -> JavaScript Tests. Ensure ‘Enable Jasmine support’ is ticked, set the correct Jasmine version, and browse for your PhantomJS executable.

Now you should be able to see your tests in the ReSharper Unit Test Explorer window:

ReSharper uses the references specified at the top of your spec files (see earlier) to know which scripts to load so it’s important you include them. With these included, your tests should now run:

The final thing you may want to do is include your Angular test suite as part of your Continuous Integration pipeline in TeamCity.

To do this, we first need to create a SpecRunner.html (or name it whatever you like) file which will host our test scripts.

In the of the HTML file we include the Jasmine CSS and JS scripts, Angular JS scripts, and our app and test JS scripts. If you are using Jasmine v2.0+, then you can include boot.js which contains the necessary initialisation for Jasmine. If you are using v1.3, then you need to include the following script:

You can test if your SpecRunner.html file is setup correctly by opening it in a browser. If it is, you should see the results from your test suite:

We can now use PhantomJS to load this HTML page and run the tests.

PhantomJS provides a run-jasmine.js script which writes out console messages based on the results from loading one of these SpecRunner HTML pages. Two GitHub users (dlidstrom and barahilia) have also usefully modified the script to output TeamCity service messages. If you are using Jasmine v1.3, grab this version; if you are using Jasmine v2.0+, grab this version. Include the script in your source code and then we can use it in TeamCity.

Test run the setup locally by running the following command (replacing with full file paths as necessary):

If it worked, you should see the following result:

If you get an error, be aware of two things that caught me out:

With all that working, all we have to do is add a build step to our configuration in TeamCity and use a command line runner to execute the command. You can either download the PhantomJS executable on your build agent, or include it in your source code and reference it from there.

When you run the build, the test results should automatically get added to the Tests tab (thanks to the service messages):

And now you have unit tests for your AngularJS app built into your TeamCity CI pipeline.

EDIT: Since writing this post, Howard van Rooijen has created a TeamCity metarunner which bundles up the PhantomJS executable and the run-jasmine scripts. Details are over on his blog post.

Unit testing AngularJS with Visual Studio, ReSharper and TeamCity