TDD

For some reason I could not get Karma and Angular to work with Jasmine on my machine and there was precious little debug help. So instead I decided to try out QUnit as the test runner inside Karma. This required some puzzling together of different blogs and other instructions so I though I'd putt it here for future reference.

Fist of all I created a new project directory. This is where all commands are executed from and all paths starts from.

Next we will need the libraries Angular and Karma-qunit. Lets start with Angular. Download it from the website. I choose the zip which includes all the Angular files. Expand the zip into lib/angular

To install Karam I use npm. Run the following command:

This will install karma-qunit into the project folder. I prefer this to using a global version since it happens all to often that tools break when upgraded and having them locally means that I can control which version is used for each project. The drawback is that in order to run karma you need to issue the command ./node_modules/karma/bin/karma every time you need to run it. To make life easier for your self you can add an alias for Karma like so:

Put the line at the bottom of your zshrc or bash_profile to ensure it's always loaded.

Next we need to configure Karma so that it can find the source code and libraries. This will also allow us to configure which browsers should be captured during testing. To do this we will use Karmas builtin init function. Run the command karma init and follow the instruction on the screen. Look at the config file below to for guidance when answering the questions.

Now that we have a configuration file there are a couple of things that may need changing. Open the file karma.conf.js in a text editor and compare it to the example config above. I made the following changes to mine:

  • In the file section there are two exploded values, I.E. values in {}. When specifying a file pattern to Karma you can either use a string or expand it to set some properties. Since we will not change the files we serve from Angular there is no need to set watchers on them which is why then are exploded. The lines below should be first in the list (make sure that the same file pattern is not in the list twice).

  • Make sure the following files are in the exclude list:
  • If you want to see more output from the running tests you can sett the logLevel value to config.LOG_DEBUG.

You should now be able to start Karma from the root of your project. When it starts it will report an error:

Firefox 26.0.0 (Mac OS X 10.9): Executed 0 of 0 ERROR (0.235 secs / 0 secs)
This is as it should be. There are no tests available and this is reported as an error. You can now leave karam running. It will detect changes to the files in js/ and test/ and rerun any tests it finds.

Now lets add our first test. To make sure the test runner works with Karma we'll start with a "non test". Since I will be testing a file called controllers.js when I write the real tests I'll add the test to the file test/controllerTests.js.

When I save the file Karma detects the change and runs the test. This should show up in your Karma console:

Firefox 26.0.0 (Mac OS X 10.9): Executed 1 of 1 SUCCESS (0.651 secs / 0.001 secs)

Lets add some real test code instead. I am going to create an application called freecycleApp. It will have a controller called NodeController. To load this into the test there is some scaffolding required so I'll add the following to test/controllerTest.js:

The module call will allow you to set up the scaffolding required to launch your Angular controller. The injector will load the application, the ctrl is your controller and the scope is the data object passed to the controller.

The first test added to test/controllerTest.js looks like this:

The test will fail, complaining that there is no module called freecycleApp so we better create it. The production code goes into the file js/controller.js.

This will create the angular module freecycleApp and the controller NodeController, which returns a list of nodes.

This should set you up to start test driving your Angular development using QUnit. Have fun!

A little while back I wrote about test driving Tornado development. This is all good and well, but how about getting instant feedback? If you are developing on a Mac or a Linux machine this is certainly possible. I found this great blog post on how to set up a change monitor on a directory that will alert you on test failures using Growl or Notify. Thanks Rodrigo Pimentel for the write up.

2 Comments

The past week I have had the pleasure to write a small web based system in python. Being a devout TDD practitioner the first step in learning python was of cause to understand the unittest module. Next thing was to see what mocking frameworks are available. To my delight I found that mockito is available for python as well (here).

The application I'm working on is a web service API to access our application using Cloud to device messaging (c2dm) from Google. To provide the web API I am using the Tornado framework.

As web frameworks goes they are usually tricky to test drive. Not so with Tornado. It ships with it's own testing framework that allows the developer to set up a round trip request/response cycle within a unit test using the tornado.testing module. Given clear module boundaries and mockito to stub out dependencies it's an easy thing to test drive Tornado web application development.

The tornado.testing module comes with a couple of very useful classes. I used AsyncHTTPTestCase to test the RequestHandler classes. To make sure that only failing tests writes to the log I also inherited LogTrapTestCase.

Below is some sample code written to allow device registration with our application server. First is the test in it's entirety and then the implementation.

The tests are in the module c2dm_registration_service_test.py:

The production code is in the module c2dm_registration_service.py:

Added to this one more class in the mondule c2dm.py. So far it is just a stub:

With this knowledge I can't find any excuses not to test drive web development in Python. It is such an easy task and takes no time at all. It is well worth the effort even when creating pilots, which most likely will end up becoming production code in the not to distant future.