Backbone Unit Tests and Continuous Integration

Posted by David Craig and Robert Curry on 13 January 2014

Backbone unit testing
Recent advances in technologies such as HTML5, CSS3, and JavaScript mean complex applications can now be delivered via the Web. Building interaction-rich web applications can create new and engaging experiences for users. For developers, managing the growth of these applications can be challenging. Fortunately there's a great range of open source solutions to help us out. Some of the more popular JavaScript frameworks are Backbone, Angular, and Ember.

We recently completed the first phase of a large application using Backbone. Part of our testing requirements was to create unit tests for the front-end application. Unit testing is a great way of ensuring individual units of code work as expected. Input values are passed into a unit of code and the output value is verified to be correct. Unit tests help find problems early in development and protect against regression issues as the project grows in size and complexity.

We found a couple of articles on unit testing Backbone applications in a web browser. This approach requires someone to visit a specific test URL to trigger the tests and view the results, then go away and fix the errors. While this approach is quick to implement and great for small projects, we wanted an automated process that integrated into our continuous integration environment.

Continuous integration encourages developers to merge their changes into the shared repository multiple times each day. This avoids conflicts (when two developers work on the same piece of code) and keeps the codebase in a healthy state. Continuous integration almost always uses automated testing - every time a developer commits a change, a full test suite is run against the latest code-base. If a change breaks any of the tests, it is instantly detected and can be fixed right away.

Running a Backbone application server-side was easy enough in theory by using Node.js. In practice it was slightly more difficult. Some client-side libraries (jQuery for example) require a window object to bind to. Node.js executes JavaScript but has no concept of a window or DOM, as it is never run inside a browser. After some experimentation and digging online we found a great Node.js library called jsdom. Jsdom creates a DOM inside a Node.js instance which our client-side libraries can bind to.

Some libraries just worked, others took some coercion. One of the main problems was the different meanings of "this" in client-side and server-side JavaScript. When running inside a browser "this" refers to the global window object. In Node.js "this" refers to the closure of the file you're in. The other major problem was the global assignment of jQuery in browsers. Again, because Node.js scoping works differently to the browser, jQuery is not global in our testing environment. Our solution for both of these issues was to create a global window object using jsdom and convert our plugins to the Asynchronous Module Definition (AMD) style, which let us pass jQuery in as a dependency reference. Once that was solved we could load various parts of our application server-side, and it was on to writing unit tests.

Mocha is the testing framework we used. It's really flexible, extendible, and allowed us to choose our assertion library and reporters. And, most importantly, it runs server-side. Mocha's syntax for writing unit tests is really nice too, you can see an example in the repository link below.

We've learned a lot integrating Backbone unit tests with our continuous integration environment. There is very little information on the topic so we have put together a boilerplate project based on our experience. Hopefully it solves some common problems and provides a useful starting point for other projects.

Head over to https://github.com/flashbackzoo/bitplate and let us know what you think.

 

David started out as a print designer creating magazine layouts and working on advertising campaigns. His love of layout and design led to an interest in the web, and how to make it user friendly. Since his shift to the web, David has worked for startups on various projects including marketing sites, campaigns, user interfaces and multi-device web applications. David enjoys discovering new music, brewing beer and looking at well designed things.

 

Robert took a circuitous route to the role of developer, dabbling in marketing and Latin before settling into the loving embrace of a Linux terminal. He was attracted to the logical and elegant nature of well-engineered software architecture and left university with a BSc in Computer Science.

Post your comment

Note: Comments are moderated and won't show until they are approved

Comments

  • Backbone is a good framework for JavaScript, the modular code that can be created with it provides great flexibility.

    Also, the event-driven communication (although I see that you've encountered some problems with it) is versatile and extensible.

    Posted by Robert, 6 months ago

RSS feed for comments on this page | RSS feed for all comments

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.