Apps, suites, and examples for Backbone.js test development.
This site provides materials and resources for developing and testing Backbone.js web applications. All of the application and test examples for the book Backbone.js Testing can be found here, grouped by chapter. We also provide a reference Backbone.js application - Notes - for creating and viewing notes, which we use throughout the examples in the book.
The core set of Backbone.js application technologies we cover includes:
We write a test infrastructure built on the following (fantastic) test libraries.
The source code for everything is available from the project's GitHub repository. If you find any errors or issues in content or code, please file a bug report and we'll fix things up in short order. For those interested in extending our testing examples or helping out, please see our contribution and development guide.
Backbone.js Testing by Ryan Roemer walks through the fundamentals of test-driven development for Backbone.js applications. All of the code samples are directly used in the book - it is essentially your narrative guide to this repository.
A short description of the book from the Packt Publishing website:
The book progresses from Mocha test suites and Chai assertions to advanced test mocks and stubs with Sinon.JS. The requisite libraries and utilities are introduced with in-depth examples and best practices for integration with your applications. The book guides you through the test planning and implementation processes for your application models, views, routers, and other Backbone.js components.
Backbone.js Testing gives you the tools, examples, and assistance to test your Backbone.js web applications thoroughly, quickly, and with confidence.
Ryan and the team at Formidable Labs assist developers, from startups to Fortune 500 companies, with all aspects of Backbone.js web application and test development. At Formidable, we lead high-impact training sessions, build out some of the world's largest Backbone.js applications, and help get new projects of any size off the ground.
Once you finish Backbone.js Testing, please reach out to us -- we'd love to accelerate your Backbone.js development and education.
The application and test samples should work for the following browser / version combinations:
See the Chai installation notes for
more compatibility information. Note that the Chai
prototype extension is not compatible with IE 9 and lower.
Notes is a simple personal note manager, written in
Backbone.js. We provide two versions - a "quick and easy"
application that works in your browser with no additional setup, and a
"classic" application with a full REST backend.
The Notes application home page lists existing notes (by creation date), and provides a form field to create a new note with a title. A filter field is available in the menu bar to limit the list of displayed notes by title.
Clicking on the edit icon brings us to the single note view, with a simple form editor for the title and text body fields of the note. The body of a note is written using Markdown formatting.
Clicking on the view menu tab switches us to the viewing pane, which renders the note's Markdown and produces our displayed note.
The Notes application is written using Bootstrap's responsive libraries and should render fine on mobile devices, tablets, and pretty much anything else.
The directory "
notes/app" contains the standalone application, which uses
HTML5 localStorage as a backing store. Some useful links to get you
An alternative version of the application uses
MongoDB instead of
localStorage for notes data and
can be found in the "
notes-rest" directory. The application is
served via a Node.js/Express
application located in "notes-rest/server.js".
Although we don't provide an online demo application, the full application
test suite is available online using Sinon.JS
fake servers to fake out the requirement
of having a real backend MongoDB server for the
tests. The test suite is nearly identical to the localStorage application tests
for all of the other tests.
The server requires Node.js and MongoDB installations. Once you have these installed, you can change into the root of this repository and install all of the project libraries:
$ npm install
To run the sample server application, you will need two terminal windows.
mongod must be available from the shell, so may need to
PATH variable. For example, on Windows, the following was
needed for some installations:
# May need to run console as Administator for just this command. $ setx PATH "%PATH%;C:\Program Files\MongoDB 2.6 Standard\bin" /M
In the first window, start up MongoDB:
# Linux / Mac $ npm run-script mongo-start # Windows (with `mongod` available from `PATH`) $ npm run-script mongo-start-win
In the second window, start up the Express server:
$ npm start
And from there you can navigate a browser to:
Note that you can control several application options by setting console environment variables:
MONGO_ADDR: MongoDB host address (default
MONGO_PORT: MongoDB port (default
ADDR: Express server host address (default
PORT: Express server port (default
For example, on a Mac:
$ export PORT=4323; npm start
runs the server on port 4323 instead of 4321 (the default).
The examples for each chapter are provided in the "chapters" directory, separated by number. We also provide a driver page for (nearly) all of the non-application tests.
Trying out the test libraries: Some first basic unit tests using Mocha, Chai, and SinonJS.
Test Failures: Different types of test failures.
Test Timing: Tests that take different times, which Mocha annotates for "medium" and "slow" tests. Also has one test timeout failure.
BDD Interface: Tests using Mocha and Chai BDD styles.
TDD Interface: Tests using Mocha
Chai Assertions: Tests using a variety of Chai BDD assertions.
chai-errors.spec.js: Exception handling.
only: Tests using the Mocha
only test modifier to run a single spec.
skip: Tests using the Mocha
skip test modifier to skip one or more specs.
Mocha Pending Tests: A basic skeleton suite with empty specs (e.g., no test callback), which are all in "pending" state during a test run. A great test development practice is to declare specs describing behavior without functions during the initial design phanse. The specs can later be implemented in parallel with the underlying application components, ensuring that the desired behavior is correctly implemented.
Tests: Continue tests for the Notes Backbone.js application.
App.Views.NoteView, which renders model Markdown data into HTML.
Sinon.JS Spies: Various test uses for Sinon.JS spies.
Tests: Tests for the Notes Backbone.js application that use Sinon.JS spies.
App.Views.NoteNavview, which mediates events for the single page navigation menu bar.
App.Views.Noteview, which wraps all of the other single note views and model.
Sinon.JS Stubs: Tests using Sinon.JS stubs.
Sinon.JS Mocks: Tests using Sinon.JS mocks.
Tests: Tests for the Notes Backbone.js application with Sinon.JS stubs and mocks.
App.Views.NotesItemview, which displays a table row for a single note in the "all notes" list.
App.Routers.Routerrouter, implementing the route matching logic, but omitting the actual view creation and display. The tests that we create a good starting point for testing routers, but please see the Notes application source for the real
App.Routers.Routersource and full "routers/router.spec.js" file.
We don't introduce any new tests in Chapter 6, instead focusing on automating all of the application and chapter tests we have provided in this respository. See the next section for a discussion of test automation with PhantomJS.
All of the tests for the Notes application and the chapter samples can be run in the PhantomJS headless WebKit engine and/or any local browsers.
Simply install the Node.js dependencies:
$ npm install
which will place an internal PhantomJS binary in "./node_modules/.bin/phantomjs" as well as all other necessary libraries.
From there, you can use the
mocha-phantomjs binary to run any HTML test
driver page from the command line, e.g.:
$ ./node_modules/.bin/mocha-phantomjs notes/test/test.html
As a helper, the following script command will run nearly all of the Notes application and chapter unit tests:
$ npm test
Karma is a multi-browser command-line test runner. It can run tests from any combination of PhantomJS and any locally installed browsers (that have a Karma test runner implemented) -- like Chrome and Firefox.
We use a Grunt plugin
grunt-karma to help configure Karma for the tests in
this project. You can run all of the tests using PhantomJS alone in Karma
with the following command:
$ node_modules/.bin/grunt karma:fast
Alternately, you can switch to "development mode" which keeps the Karma test engine running (which we've configured to use PhantomJS, Chrome and Firefox) with:
$ node_modules/.bin/grunt karma:dev
This process then waits for test invocations, which you can do by opening a second terminal in the same directory and typing:
$ ./node_modules/.bin/karma run
This two-terminal approach saves you the overhead of firing up all of the browser environments in which to run the test suites.
We run all of these tests automatically using (the awesome) Travis CI continuous integration service. Travis watches the GitHub repository containing this project and when it detects the code has changed, launches new builds and invokes the PhantomJS tests above.
Travis even provides a convenient image status indicator, that we display below, so that we can display the always current build status of our code. Additionally, we run our Karma tests through a coverage reporter that uploads to Coveralls, so we have a coverage report as well:
Setting all of this up is as simple as adding a Travis configuration file ".travis.yml" as follows:
language: node_js node_js: - 0.10
This instructs Travis to test out the latest Node.js versions for v0.8 and
v0.10. By default, Travis already has PhantomJS installed and will run
npm install and
npm test on any Node.js project, which conveniently
sets up and invokes all of our PhantomJS tests.
Our actual ".travis.yml" file runs different commands than
npm test to add things like style checking. But, the overall
Travis configuration is essentially the same.
We also do multi-browser testing of the frontend code thanks to generous donations of VM time from Sauce Labs and BrowserStack. Here's our build matrix:
There are many additional testing libraries and plugins specifically suited to testing Backbone.js applications beyond the core test stack we use in the application and chapter examples above.
Chai has a rich plugin ecosystem, with libraries that enhance the core Chai assertion statement library, provide more specific failure messages, and make application behavior easier to express.
Plugins that are used in some examples:
expect(spy).to.have.been.calledWith(42)instead of the Sinon.JS native
Additional plugins not used in the examples:
All frontend libraries used in this repository for the sample apps and chapter examples are provided in the "vendor" directory.
Note that this repository has been updated since the publication of Backbone.js Testing on July 12, 2013. The enumerated versions of all third party libraries are indicated by the most current version in the repository with the published version noted in parenthesis when different.
The core Backbone.js components used are:
The sample Notes application also uses:
The frontend test libraries we use are:
The test plugins include:
The repository was tagged with git as
published-1.0 for the code samples
that are shipped with the book as it went to press. To check out the published
version in this repository, type:
$ git checkout tags/published-1.0
This will switch all libraries, application code, and tests to the version that directly matches the book.
As of v3.x.x and higher, Mocha-PhantomJS requires PhantomJS v1.9.1 or higher.
Mocha version 1.10.0 and 1.11.0 introduced incompatibilities with Mocha-PhantomJS. Modern versions of both libraries are now compatible, e.g., Mocha v1.12.0+ and Mocha-PhantomJS v3.1.0+.
For this historically minded, the evolution of this issue is documented in the following tickets:
Backbone.js Testing shipped with Mocha v1.9.0 and Mocha-PhantomJS v2.0.3 to avoid the issue.
All code not otherwise specified is Copyright 2013 Ryan Roemer. Released under the MIT License.
This repository contains various libraries from other folks, and are licensed as follows:
Backbone.js is Copyright Jeremy Ashkenas and licensed under the MIT license.
Underscore.js is Copyright Jeremy Ashkenas and licensed under the MIT license.
jQuery is Copyright jQuery Foundation and licensed under the MIT license.
Backbone.localStorage is Copyright Jerome Gravel-Niquet and licensed under the MIT license.
JSON is Public Domain software created by Douglas Crockford.
Mocha is Copyright TJ Holowaychuk and licensed under the MIT license.
Chai is Copyright Jake Luer and licensed under the BSD license.
Sinon-Chai is Copyright Domenic Denicola and licensed under what we will politely approximate to a "public domain" license.
Sinon.JS is Copyright Christian Johansen and licensed under the BSD license.
Twitter Bootstrap is Copyright Twitter, Inc. and licensed under the Apache v2.0 license.
Jasny Bootstrap is Copyright Twitter, Inc. and Jasny BV and licensed under the Apache v2.0 license.
Showdown is Copyright Corey Innis and licensed under the BSD license.
Mocha-PhantomJS is Copyright Ken Collins and licensed under the MIT license.
Blanket.js is Copyright Alex Seville and licensed under the MIT license.
For those who would like to get under the hood, or help out with the application or test examples.
For pretty much everything, you will need to install a Node.js environment, and the development NPM dependencies:
$ npm install
From there, there are various Grunt script helpers for style checking and tests:
# Run style checks for server, client, and both. $ node_modules/.bin/grunt jshint:server $ node_modules/.bin/grunt jshint:client $ node_modules/.bin/grunt jshint # Run headless tests for the application, individual chapters, all chapters # as one big test, and all of these together. $ node_modules/.bin/grunt test:app $ node_modules/.bin/grunt test:rest $ node_modules/.bin/grunt test:chaps $ node_modules/.bin/grunt test:chaps-all $ node_modules/.bin/grunt test # Run all style checks and headless tests. $ node_modules/.bin/grunt check
The file "README.md" is transformed from markdown into the HTML page "index.html", and can be compiled once, or watched for changes with the following commands.
$ node_modules/.bin/grunt jade:docs $ node_modules/.bin/grunt watch:docs
We internally use bower to get / upgrade our vendor libraries. To update these, do the following:
$ node_modules/.bin/bower install $ node_modules/.bin/grunt build:vendor
We internall synchronize the
notes application and test files to
overwriting the latter. To do this:
$ node_modules/.bin/grunt build:notes-rest
Note: This overwrites files in
notes-rest, so don't invoke this if
you intend to change those files!
Finally, we have a lot of other builds (templates, docs, etc), that are all aggregated as part of:
$ node_modules/.bin/grunt build
in addition to the tasks described above.
Bugs, issues and fixes for any of the application or test code examples are most welcome. Please file a GitHub issue or pull request for any changes. Pull requests should be able to pass
$ node_modules/.bin/grunt check
without any errors.
srcattribute link to TDD example test file. The Chapter 3 file "tdd.spec.js" in the samples should have been named "tdd.js". The text of the book remains correct - only the code sample has been updated. (@aserputko)