Functional Testing with Sparrow

Jonathan Freeman

 4 min read

Always interested in new approaches to testing on the front end, my ears perked when a functional testing framework called Sparrow.js popped up in my twitter stream. In essence, Sparrow allows you to run Selenium style tests defined with Jasmine style syntax. The immediate appeal for me was that front-end developers with experience in Jasmine could easily side-step into using Sparrow to write tests for broad user interactions that span across multiple pages. I played around with it for an afternoon, and here's what I learned.

Tests at a glance

A simple sparrow test looks like this:

loading

The describe, it, and expect methods are provided by Jasmine, and are used to organize your tests into suites (describe), individual tests(it), and to define your expectations(expect(...)). The rest is provided by Sparrow. Let's break it down line by line.

loading

We define a new test window which creates a variable that we can access in our current scope called $listWin.

loading

This creates a chainable object that we can call methods on in order to define the flow of our test.

loading

Here's where the meat of the test actually lives. We're telling our test window to open the Spantree home page, click on the blog link, wait for it to load, and then execute an anonymous function that will look for and expect that something with sparrow in the title is present on the page.

loading

This is just a signal to the object that we're done setting up the chain of events and we can kick them off.

Same origin rules

Each test window you create is actually an iframe, which is an interesting appraoch to use. A new iframe is appended to the DOM and it can be manipulated via the parent page. This allows us to run tests that involve navigating around a web page while maintaining an execution context within which to keep track of where you are and test some expected outcome. The only drawback is that browsers will throw security warnings at you and prevent you from even accessing the iframe content if you're not using the same protocol, host and port. That means that if I try to run the example test above, it will fail for security reasons unless I actually deploy it to spantree.net and run it there. That's probably not a great idea, but you also probably want to run your functional tests locally, not in production.

Installation and generating tests

Here's where some pain is introduced, but that's not tremendously surprising considering the project surfaced on GitHub less than three weeks ago. Currently the process involves downloading a zipped release folder, finding the best place to unzip it, and installing its dependencies. This is far from the npm install sparrow-test that I'd prefer. It would also be great to have hooks into the build tool of your choice. These are things that the creator is interested in doing, but I imagine ironing out the kinks is much higher on the priority list than writing a plugin for broccoli.

There is also an intermediate step between writing your tests and running your tests if you want to run them in a browser (Sparrow supports headless testing with phantomjs). You have to run a jasmine grunt task to generate specRunner.html which is a tedious bit of ceremony. As the project makes its way towards a standalone, easily distributable library, I imagine this step will be abstracted away, but in the mean time you can easily add a watch task and rebuild specRunner.html whenever you make changes to the specs directory.

All in all, Sparrow is a very young functional testing library with an interesting approach. I'm interested in seeing how it progresses and will continue playing with it on my personal projects. There are places where the paint hasn't dried yet so I hesitate to incorporate it into client projects, but I'm looking forward to the time when I can.