AngularJS–Part 8, More choice when testing


Introduction

This is a series of posts about AngularJS and our experiences with it while migrating the client of a complex enterprise application from Silverlight to HTML5/CSS/JavaScript using AngularJS as a framework. Since the migration is a very ambitious undertaken I want to try to chop the overall problem space in much smaller pieces that can be swallowed and digested much more easily by any member of my team. So far I have published the following posts in this series

  • AngularJS – Part 1
    • AngularJS – Part 1, Feedback
      • AngularJS – Part 2, the controller
        • AngularJS – Part 3, Inheritance
          • AngularJS – Part 4, Accessing server side resources
            • AngularJS- Part 5, Pushing data to the server

              While digging a bit deeper into the world of testing in and around Angular I was made aware of testem, another awesome framework agnostic test runner. This test runner is extremely simple to setup and we are up and running in no time.

              I am assuming that you have installed node.js on your system (if not, what are you waiting for?). Open a console and run the following command to use the node package manager to install testem.

              image

              That’s all. Really! It will install testem on your system and make it available globally.

              A first test

              Create an empty directory, e.g. HelloWorld and navigate to this directory

              image

              Now run testem

              image

              you will be presented by a console output similar to this

              image

              Now start your favorite browser(s) and point them to the URL shown in the console (here http://localhost:7357). Now the console changes and we’re getting the feedback that the browser(s) are connected. I this sample I have started Chrome and Firefox.

              image

              Everything is ready to go. As soon as there are any tests available testem will run them on both connected browsers. We can use right and left key in the console to switch between the output for the two browsers.

              Let’s write a very simple test using Jasmine. For this create a new file testSpec.js and add this code

              image

              In the above test we want to make sure that when calling a function hello() the return value is “Hello John”. The moment you save this file testem is triggered and runs the test. The output on my system looks like this

              image

              The test obviously has failed since we didn’t implement a function hello so far. The error clearly states this fact. Let’s implement the function hello. Add another file called test.js to the directory and add the following code to it

              image

              When you now save this file testem is again triggered and runs the test. This time the test succeeds.

              image

              A unit test for Angular

              Now let’s write a unit test for Angular. For brevity will just copy the test from my last post. Add a new file sampleSpec.js to the directory and add the following code

              image

              With this code we want to test a simple Angular controller and verify that the controller initializes a property hello on its $scope with the value “Hello John.”. Once we save this file testem shows us the following error

              image

              Of course, we forgot to provide the angular.js and angular-mocks.js to the sample (and to testem). Thus let’s copy those two files into our HelloWorld directory. Once we have done so, testem still is not happy and reports this error

              image

              This error is somewhat similar to the previous one but the last line in the stack trace give us a hint that something is wrong with the angular-mocks.js file. It seems that testem picks the two angular files up in the wrong order. It should first load angular.js and only then angular-mocks.js since the latter depends on the former. Ok, what can we do? Searching the internet did not help much… But wait a second, there is an option to explicitly configure testem by defining a testem.json file in the working directory. Let’s try this and add the following configuration to this file

              image

              Quit the currently running instance of testem by pressing “q” in the console and restart it such as that it can pick up the just defined configuration. The test still fails, but this time not because of angular or angular-mocks because but because the controller is not yet defined. Let’s add a file sample.js to the working directory and add this code

              image

              When we now save the file the test will pass and testem will output this

              image

              Conclusion

              In this post I have introduced testem, another very powerful test runner besides karma for JavaScript tests. This runner is easy to install and straight forward to use. Now we have at least two ways how we can run our unit tests while developing our Angular SPA application, both of which are pretty much friction less.

AngularJS–Part 7, Getting ready to test