Functional Testing with Sparrow
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:
loadingThe 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.
We define a new test window which creates a variable that we can access
in our current scope called $listWin
.
This creates a chainable object that we can call methods on in order to define the flow of our test.
loadingHere'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.
loadingThis 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.