Chili Pepper Design

Web development relleno

JavaScript Unit Testing With Jasmine, PhantomJs and Karma

| Comments

NOTE: This article was accidentally published before it was completed. It’s still not complete, but it’s close, so rather than take it down I’ll leave it up.

I do not practice Test Drive Design (TDD). I do try to fill in unit tests to code if I have time, for regression testing, but that is far from the ideals of TDD. I keep hearing great things about it though, and enjoyed a little crash course put on by the UtahJS user group. Part of a project I am working on at SplashLab is a standalone JS app for collecting web analytics. This seemed like a good time to try out some TDD.

Getting the JavaScript testing framework Jasmine up and running in a web browser is fairly simple, but you have to reload the page to run your unit tests. Also, it’s awkward to work combine JS unit tests with PHP unit tests, which run in the console. We don’t have a Continue Integration server running, but I would like to some day, so a way to run our frontend JS tests along with our PHP tests would be ideal.

I’m not the only person to think this would be nice, and at the UtahJS meetup I (re)learned about an automated command-line JS testing tool called Karma (formerly Testacular, the “test framework with balls” - strange to think they didn’t stick with that classy name…). This is a NodeJS script which uses headless (i.e. not-rendered-to-the-screen) web browsers to run your JS unit tests in the command line. It watches your unit test and the code under test, automatically re-running your unit tests as you develop. This sounded perfect for my first foray into TDD, and I think it will be useful in the future for building CI test suites.

I am running on Windows, which is recipe for pain when attempting to use trendy new dev tools, so I fired up a Vagrant virtual box (Ubuntu 12.04) to set up my Karma testing scripts. Using Vagrant means, as this article was kind enough to point out (, that I wouldn’t be able to use the standard Chrome browser for my Karma tests, and would have to use something like PhantomJS - a true headless Webkit browser engine for the command line. This will be fine for now. As my project nears completion I will look for a way to run these unit tests in other browsers - even it means manually firing up the Jasmine SpecRunner page. But for now PhantomJS will work to get my automated background tests running.

The first part was simple:

$ apt-get install nodejs
$ apt-get install npm
$ npm install -g karma    // -g for global install
$ npm install phantomjs

I set up Vagrant to have a Synced code folder, so I can still edit my code in the Windows WebStorm IDE, but have the tests running in the background in Vagrant.

The first time I tried this I didn’t install phantomjs with npm, but with apt-get. I problem I ran in to (which I should have saved the error I had to Google for) was something to do with font rendering, and I had to also install libfontconfig1. It will probably work better with the npn install.

Karma comes configured to work with PhantomJS by default, without needing to install any plugins.

To get Karma set up, run in the karma init command. This will walk you through some basic setup option with a commandline wizard. This generates the karma.conf.js configuration file.

One thing that confused me is that many tutorials online are for older version of Karma, where you needed to add options like JASMINE_ADAPTER to the configuration file. Now it appears all you need to do is specify the frameworks option in the config file to your JS testing framework of choice - jasmine in this case.

So all you need to have in ‘files’ now is the code you are testing, and the test specs.

I am developing a single script as multiple files, which will be concatenated together in the build process. To keep my simple project simple, I decided not to use any of the CommonJS ‘require’ strategies, and intend to just concatenate the final file in a certain order. Using the standard Jasmine SpecRunner.html file for testing, I would just list the <script> tags in the correct order, so all the dependencies in my code are met properly. Many of the example Karma configurations just load all of the code to be tested with a wildcard though, like so: ‘/src/*.js’. This might be fine if you are using require.js or something, but I found the wildcard script load order was not necessarily what I needed it to be (is it random?), so I had to declare each .js file under test individually, just like in SpecRunner, to maintain the proper load order.

I will say, against all odds, Karma is working well directly on Windows. Although it is surprisingly slow - with Chrome at least (have not tried other plugins).