My first challenge when I decided to adopt Node.js to develop web applications was to find out how to write end-to-end/acceptance tests. My workflow to develop something new usually starts with a high-level feature test, so finding something like capybara for Ruby/Rack and RSpec was the logical first step.
I started picking up Mocha as a test framework. It supports the BDD-style that I like in RSpec and has different kind of reporters, styles of writing tests (called interfaces), configurations and integrations that I’ll probably never touch. I also added Chai, an assertion library, to be able to write nice assertions like:
Finding a test library was very easy since there is a lot of those in the JavaScript world (Ex: qunit, jasmine). My goal was to write something like this:
The best library that I found for this was Zombie.js. Although not perfect, it is definitely the most capybara-like testing framework currently available in the Node.js ecosystem. The code above would have been written like this using Zombie.js, Mocha and Chai:
Not bad, right? The only real cons is having to write plumbing to spin up the webserver and configure the browser (capybara handles all of this by himself). This plumbing is hidden inside the browserContext method call, right below the describe. Here is my current implementation to test an Express app using Socket.io for WebSockets:
Since the test suite needs the Express app without the webserver attached, something like the code below is required to export the app object:
Although not ideal, all of this complexity can be hidden within just one method call in your test suite.
Zombie.js looks very mature and support a lot of stuff - WebSockets, Server-Sent Events, cookies and WebStorage, XMLHttpRequest… basically everything you might need.
I also found two alternatives to Zombie.js: phantomjs and the famous selenium-webdriver. I couldn’t find any stable looking library that used phantomjs, so I wouldn’t choose it right now (although I’m a fan of the poltergeist gem of Ruby). Selenium-webdriver looks usable, but I would like to avoid it if possible due to “not so nice” memories.
I’m writing tests like this in my dashy project - a small framework to create “realtime” dashboards using Node.js, WebSockets and Angularjs. It’s just an experiment for now (since I’m exploring different things and ways of writing this kind of app using Node.js), but it’s improving every day and I expect it to be usable in a month. You can find there examples of different kinds of tests in JavaScript (unit, integration, feature/acceptance).