As OSCON Wraps Up, Urban Airship Celebrates Open Source

Open source is part of our DNA here at the Airship. Sitting here between the much larger technology communities of Silicon Valley and Seattle, Portland has the unique distinction of being at the epicenter of the open source software industry with leading foundations, businesses and a vibrant and growing tech community.

Portland has been the host city for most of the OSCON shows, and we were the first city in the US to adopt a formal policy in support of opening data to outside developers and adopting open source solutions in technology procurement. In fact, our CEO and co-founder Scott Kveton co-founded the Open Source Lab at Oregon State University, which was instrumental in helping several open source projects grow into mainstream usage, including the Mozilla Foundation, the Linux Kernel and Drupal.

As OSCON comes to a close, we’ll demonstrate our updated integration with PhoneGap, which was purchased by Adobe and contributed to the Apache Software Foundation to start a new project called Apache Cordova. Developers using the latest version of the open source mobile development framework will be able to easily add the full push messaging capabilities of Urban Airship to their iOS and Android apps in order to grow engagement and user retention.

Joining other recent open source projects, today we are detailing our latest contribution by Chris Dickinson—Drive.js for JavaScript unit testing. JavaScript code is written to run in a lot of disparate environments, each of which must be tested locally against every code change using multiple virtual machines. This is a hassle, takes a lot of time and acceptance testing just gives you a “yes” or “no” to whether the code works versus knowing what’s broken, which environments spawn which errors and which code isn’t covered by the tests.

JavaScript doesn’t ship with a module loader and its hard to localize changes when you don’t have modules to tie them to, especially when you’re concatenating the entire codebase down to a single, order-dependent minified string. So, you’ll need to pick a module loader in order to have more testable code, and while it doesn’t matter which one you choose it will influence how you write your libraries and impact other options such as asset packaging. We chose require.js because it provides a decent story for production and a great story for development, as well as providing “sync looking” require statements.

Once we had the module loader in place, we developed Drive.js to solve the rest of the issues we experienced with testing JavaScript, and generally offer our developers a much more humane testing process where they don’t have to leave their terminals. Drive.js formats test failures and errors in a helpful fashion, providing file context in stack traces. It’s designed to work with require.js and encourage writing self-contained modules. Check it out on GitHub and read how to get started.

A simple command:

drive ..

runs the tests in a local JSDom node environment for quick smoke testing of recent changes. When you're fairly sure your changes work, you can simply point drive at a driver url:

drive . --driver host:port

to run the tests in all environments available on the drive server. Or you can narrow the scope of your tests with

--want

which matches particular environments e.g.

drive . --driver host:port --want chrome --want ie
  • All console logs are piped to your terminal locally and annotated with the environment that produced them.
  • All requested media is piped from your local computer, through the drive server, and into the browser.
  • All test runs are namespaced, and all media is served under that namespace, so the target browsers will never cache that data.

Writing tests

  • Designed to feel similar to mocha’s TDD api.
  • Provides the node assert module.
  • You can specify the HTML to be served with your test suite by providing a relative path to that HTML file.
  • You can mock out XHR endpoints relative to the namespaced test suite.
  • You can specify that XHR requests going to one URL should hit a namespaced URL instead (useful for testing code that contains hard coded XHR endpoints).
  • Tests may be synchronous or asynchronous.
  • Full access to require.

Goodies

  • Tests may be run with code coverage.
  • Test servers may be configured to automatically include pre-defined media (e.g., jQuery, or any other library not wrapped in AMD raiment).
  • Test servers accept an adaptor module that can redirect test metrics to another test result aggregation server (or simply output debug information about test runs).